Java ListView.getItems().removeAll()中的可疑行为

Java ListView.getItems().removeAll()中的可疑行为,java,list,generics,user-interface,javafx,Java,List,Generics,User Interface,Javafx,如果我有一个包含4个对象(不完全相同)的列表,我调用JavaFX的listView.getItems().removeAll(listView.getSelectionModel().getSelectedItems()),并选择一个对象(比如数字1),那么对象2和3也将被删除。这是removeAll()的正常操作吗?这导致了一个相当令人沮丧的错误。这在removeAll()方法中没有记录,这是相当误导的,因为我使用了它,因为它比普通的remove方法具有更好的类型安全性,该方法使用对象当您删除

如果我有一个包含4个对象(不完全相同)的列表,我调用JavaFX的
listView.getItems().removeAll(listView.getSelectionModel().getSelectedItems())
,并选择一个对象(比如数字1),那么对象2和3也将被删除。这是
removeAll()
的正常操作吗?这导致了一个相当令人沮丧的错误。这在
removeAll()
方法中没有记录,这是相当误导的,因为我使用了它,因为它比普通的
remove
方法具有更好的类型安全性,该方法使用
对象

当您删除选定的项目时,该选择将被更新,以便选择其他项目。更新选择时,这会产生副作用,即更新由
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()));
    
    list.getItems().removeAll(新的ArrayList(list.getSelectionModel().getSelectedItems());
    
    确保已正确实现listView中项目类型的
    equals()
    。@Eng.Fouad
    equals
    hashcode
    已被覆盖。它们是不同的物体。哇,太疯狂了。第一次发生的时候,我很惊讶。我想这是学习曲线的一部分。@SarahSzabo是的,这是学习曲线的一部分,但坦率地说,API对我来说有点味道。从纯集合的角度来看,
    List.removeAll(list2)
    希望list2在调用期间不会改变。但是从
    multipleSelectModel.getSelectedItems
    返回的
    ObservableList
    始终保持与选择相关的最新信息。因此,如果您想使用当前选择作为更新选择的计算的一部分——这似乎完全合理——您会遇到麻烦。