如果我有一个包含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()));

07-26 02:59