如何从具有重复条目的筛选列表中删除特定索引?

时间:2018-01-28 20:14:11

标签: java javafx

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

用户可以在public void removeItemsAtIndices ( List <Integer> indices ) { List <Item> removeMe = new ArrayList<Item> (); for ( int index : indices ) { removeMe.add( currentListSorted.get( index ) ); } items.removeAll( removeMe ); } 上选择行,然后按删除。当他们这样做时,应该删除所选择的项目,而不删除其他项目。

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

在底层ObservableList上使用list.remove(Object) - 由于列表可以包含重复项,因此将删除该对象的所有副本,而不仅仅是选定的副本。

UnsupportedOperationException

在SortedList上使用list.remove(index) - 过滤后的列表会抛出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 );

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

list.get(5) == list.get(10)

有没有办法删除项目:

  1. 从排序列表中
  2. 根据过滤后的指标进行定位。排序清单
  3. 不删除非目标重复项?
  4. 目前我能想出的唯一解决方案就是让每个项目都是唯一的(即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 ); } }); }是不可能的。我希望通过寻找另一种解决方案来避免这种情况。

    P.S。如果由于某种原因它是有用的,这里是确定所选索引的代码:

    Mail Protocol: smtp
    Mail Parameters: -fmyemail@gmail.com
    SMTP Hostname : ssl://smtp.gmail.com
    SMTP Username : myemail@gmail.com
    SMTP Password : my email password
    SMTP Port : 465
    SMTP Timeout : 5
    

1 个答案:

答案 0 :(得分:2)

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());
}