java 特定索引的Java流过滤项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36294051/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java stream filter items of specific index
提问by Vedanth
I'm looking for a concise way to filter out items in a List at a particular index. My example input looks like this:
我正在寻找一种简洁的方法来过滤列表中特定索引处的项目。我的示例输入如下所示:
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);
I want to filter out items at index 2
, 4
, 6
, 8
. I have a for loop that skips items that match the index but I was hoping there would be an easy way of doing it using streams. The final result would look like that:
我想过滤掉 index 2
, 4
, 6
, 处的项目8
。我有一个 for 循环,它跳过与索引匹配的项目,但我希望有一种使用流的简单方法。最终结果如下所示:
List<Double> filteredList = Arrays.asList(0.0, 1.0, 3.0, 5.0, 7.0, 9.0, 10.0);
回答by Alexis C.
You can generate an IntStream
to mimic the indices of the original list, then remove the ones that are in the filteredIndexes
list and then map those indices to their corresponding element in the list (a better way would be to have a HashSet<Integer>
for indices since they are unique by definition so that contains
is a constant time operation).
您可以生成一个IntStream
来模拟原始列表的索引,然后删除列表中的索引,然后将filteredIndexes
这些索引映射到列表中的相应元素(更好的方法是使用HashSet<Integer>
for 索引,因为它们是唯一的)定义,所以这contains
是一个恒定的时间操作)。
List<Double> filteredList =
IntStream.range(0, originalList.size())
.filter(i -> !filterIndexes.contains(i))
.mapToObj(originalList::get)
.collect(Collectors.toList());
回答by Tagir Valeev
If your filteredIndexes
list is presorted, you can avoid checking every element in this way:
如果您的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());
Here we create a number of sublists which contain all the elements between the filtered indices, then just flatten them into the single final list. For big input (e.g. a million of numbers) this solution could be magnitudes faster than one proposed by @AlexisC.
在这里,我们创建了许多子列表,其中包含过滤索引之间的所有元素,然后将它们展平到单个最终列表中。对于大输入(例如一百万个数字),此解决方案可能比@AlexisC 提出的解决方案快得多。
回答by slartidan
If you sort your indexes descending, then you can use java.util.List.remove(int)
to remove the items.
如果您对索引进行降序排序,则可以使用java.util.List.remove(int)
删除项目。
List<Double> originalList = new ArrayList<>(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);
filterIndexes.stream()
// remove higher indixes first, because each remove affects all indexes to the right
.sorted(Comparator.reverseOrder())
// make sure to use remove(int) not remove(Object) in java.util.List to use indexes
.mapToInt(Integer::intValue)
// remove each index
.forEach(originalList::remove);
// print results
originalList.forEach(System.out::println);