特定索引的 Java 流过滤器项

2022-09-03 04:50:24

我正在寻找一种简洁的方法来过滤掉特定索引的List中的项目。我的示例输入如下所示:

List<Double> originalList = Arrays.asList(0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0);
List<Integer> filterIndexes = Arrays.asList(2, 4, 6, 8);

我想过滤掉索引 、 处的项目。我有一个for循环,可以跳过与索引匹配的项目,但我希望有一种使用流的简单方法。最终结果如下所示:2468

List<Double> filteredList = Arrays.asList(0.0, 1.0, 3.0, 5.0, 7.0, 9.0, 10.0);

答案 1

您可以生成一个来模仿原始列表的索引,然后删除列表中的索引,然后将这些索引映射到列表中的相应元素(更好的方法是使用 for 索引,因为它们在定义上是唯一的,因此这是一个常量时间操作)。IntStreamfilteredIndexesHashSet<Integer>contains

List<Double> filteredList = 
    IntStream.range(0, originalList.size())
             .filter(i -> !filterIndexes.contains(i))
             .mapToObj(originalList::get)
             .collect(Collectors.toList());

答案 2

如果您的列表是预先排序的,则可以避免以这种方式检查每个元素:filteredIndexes

List<Double> filteredList = IntStream.rangeClosed(0, filterIndexes.size())
    .mapToObj(idxPos -> idxPos == 0 
           ? originalList.subList(0, filterIndexes.get(idxPos)) 
           : idxPos == filterIndexes.size() 
           ? originalList.subList(filterIndexes.get(idxPos-1)+1, originalList.size()) 
           : originalList.subList(filterIndexes.get(idxPos-1)+1, filterIndexes.get(idxPos)))
    .flatMap(List::stream)
    .collect(Collectors.toList());

在这里,我们创建了许多子列表,其中包含过滤索引之间的所有元素,然后将它们平展到单个最终列表中。对于大输入(例如一百万个数字),这个解决方案可能比@AlexisC提出的解决方案快得多。


推荐