[英]Java stream filter items of specific index
我正在尋找一種簡潔的方法來過濾列表中特定索引處的項目。 我的示例輸入如下所示:
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);
我想篩選出在索引項2
, 4
, 6
, 8
。 我有一個for循環,它會跳過與索引匹配的項目,但是我希望會有一種使用流的簡單方法。 最終結果將如下所示:
List<Double> filteredList = Arrays.asList(0.0, 1.0, 3.0, 5.0, 7.0, 9.0, 10.0);
您可以生成一個IntStream
來模仿原始列表的索引,然后刪除filteredIndexes
列表中的索引,然后將這些索引映射到列表中的相應元素(一種更好的方法是將HashSet<Integer>
用於索引,因為它們在定義上是唯一的,因此contains
是恆定時間操作)。
List<Double> filteredList =
IntStream.range(0, originalList.size())
.filter(i -> !filterIndexes.contains(i))
.mapToObj(originalList::get)
.collect(Collectors.toList());
如果您的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提出的解決方案快幾個數量級。
如果按降序對索引排序,則可以使用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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.