如果我有一个包含4个对象的列表(不是全部相同),并且我调用JavaFX的listView.getItems().removeAll(listView.getSelectionModel().getSelectedItems())
并且选择了一个对象(比如说1),那么对象2和3也将被删除。这是removeAll()
的正常操作吗?这导致了一个相当令人沮丧的错误。这没有在removeAll()
方法中记录,而是令人误解,因为我使用它是因为它比采用remove
的常规Object
方法具有更好的类型安全性。
最佳答案
删除所选项目时,所选内容将被更新,以便选择其他项目。更新选择时,这具有更新listView.getSelectionModel().getSelectedItems()
返回的列表的副作用。这与List.removeAll
方法交互不良。
假设我们有targetList.removeAll(removeList)
。对于targetList
中的每个元素,代码都会问:“此元素是否出现在removeList
中?”如果是这样,将从targetList
中删除该元素。这会对removeList
产生副作用,从而在下次循环时更改行为。
进一步来说:
这从元素0开始。由于此元素未出现在removeList
中,因此什么也没有发生。
接下来是元素1。由于已选择它,因此它出现在removeList
中,因此元素1被删除。 ListView
代码检测到所选元素已被删除,因此将所选内容更新为元素2。这意味着removeList
现在包含元素2。
接下来是元素2。由于已选择它,因此它出现在removeList
中,因此元素2被删除。 ListView
代码检测到所选元素已被删除,因此将所选内容更新为元素3。这意味着removeList
现在包含元素3。
我认为您可以看到现在发生的情况。 :-)
解决此问题的最简单方法是在将选择列表传递给removeAll
之前复制选择列表:
list.getItems().removeAll(new ArrayList<>(list.getSelectionModel().getSelectedItems()));