java - 如何从具有重复条目的过滤列表中删除特定索引?

标签 java javafx

我有一个TableView,由一个SortedList支持,包装一个FilteredList,包装一个ObservableList。过滤列表中的项目可以重复。也就是说,可能是list.get(5) == list.get(10)的情况。

用户可以在TableView 上选择行并按删除键。当他们这样做时,所选择的项目应该被删除,而不是其他项目。

我尝试了两种解决方案,但都存在问题:

在基础 ObservableList 上使用 list.remove ( Object ) - 因为列表可能包含重复的项目,所以对象的所有副本都会被删除,而不仅仅是选定的副本。

public void removeItemsAtIndices ( List <Integer> indices ) {

    List <Item> removeMe = new ArrayList<Item> ();

    for ( int index : indices ) {
        removeMe.add( currentListSorted.get( index ) );
    }

    items.removeAll( removeMe );
}

在 SortedList 上使用 list.remove (index) - 过滤后的列表会引发 UnsupportedOperationException

public void removeItemsAtIndices ( List <Integer> indices ) {
    Collections.sort( indices, Collections.reverseOrder() );

    for( int index : indices ) {
        currentListSorted.remove( index ); //Exception here
    }
}

以下是我设置列表的方法:

private final ObservableList <Item> items = FXCollections.observableArrayList(); 
private final FilteredList <Item> currentListFiltered = new FilteredList <Item>( items, p -> true );
private final SortedList <Item> currentListSorted = new SortedList <CurrentListTrack>( currentListFiltered );

有没有办法删除项目:

  1. 来自排序列表
  2. 按已过滤和排序列表的索引进行定位
  3. 不删除非目标重复项?

目前我能想到的唯一解决方案是使每个项目都是唯一的(即不可能 list.get(5) == list.get(10)) 。我希望通过寻找另一种解决方案来避免这种情况。


附注如果由于某种原因它有用,下面是确定所选索引的代码:

removeMenuItem.setOnAction( new EventHandler <ActionEvent>() {
    @Override
    public void handle ( ActionEvent event ) {
        ObservableList <Integer> selectedIndexes = currentListTable.getSelectionModel().getSelectedIndices();
        List <Integer> removeMe = new ArrayList<> ( selectedIndexes );
        removeItemsAtIndices ( removeMe );
    }
});

最佳答案

TransformationList(其中 SortedListFilteredList 都是实现)具有 getSourceIndex(int index)将转换列表中的索引“转换”为其源(底层)列表中的索引的方法。因此,currentListSorted(index)给出了排序列表中具有所提供索引的项目在过滤列表中的索引,而currentListFiltered(index)给出了原始列表中的索引items 在过滤列表中具有所提供索引的项目列表。

所以你可以这样做

items.remove(currentListFiltered.getSourceIndex(
    currentListSorted.getSourceIndex(index)
));

删除可见表项(排序列表)“索引坐标”中特定索引处的项。

当然,您需要小心代码中的循环,因为删除项目时索引会发生变化。 (如果您只是从简单列表中按索引删除项目,这也是正确的。)

所以您可能需要以下内容:

List<Integer> indicesToBeRemoved = new ArrayList<>();
for (int index : indices) { // indices in the sorted list
    indicesToBeRemoved.add(currentListFiltered.getSourceIndex(
        currentListSorted.getSourceIndex(index)));
}
// sort with largest index first, as removing an item with
// a given index will not change the indices of items with small indices:
indicesToBeRemoved.sort(Comparator.reverseOrder()); 
for (Integer index : indicesToBeRemoved) {
    // be careful to explicitly unbox the Integer here, 
    // to avoid collision between remove(Object) and remove(int):
    items.remove(index.intValue());
}

关于java - 如何从具有重复条目的过滤列表中删除特定索引?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48490831/

相关文章:

java - 将生产代码修改为可测试/仅用于测试目的是最佳做法吗?

java - 正则表达式使用java获取第一个斜杠后的所有字符

java - ICEfaces:如何禁用某些表单的发送接收更新机制

java - android studio 项目到 javaFX?

javafx - 同步两个滚动条JavaFX

未创建 javafx Pane

java : execute a method over a maximum period of time

java - 关于 javafx webview 和 javafx 动画,svg

java - 警告 : Loading FXML document with JavaFX API of version 9 by JavaFX runtime of version 8. 0.131

java - 为什么缺少授权 header ?