【问题标题】:How can I filter elements of the list based on their index(position) using stream() in Java?如何使用 Java 中的 stream() 根据索引(位置)过滤列表中的元素?
【发布时间】:2019-06-05 08:00:53
【问题描述】:

如何在 Java 中使用 stream() 根据索引(位置)过滤列表中的元素? 我想过滤每三个元素(即List<String> 的索引 0、3、6、9、...)。

【问题讨论】:

  • 你有没有尝试过?
  • 到目前为止你有什么尝试?

标签: java java-stream


【解决方案1】:

从 Java 9 开始,您可以使用 IntStream.iterate() 来实现:

IntStream.iterate(0, i -> i < list.size(), i -> i + 3)
        .mapToObj(list::get)
        .forEach(System.out::println);

如果你使用的是 Java 8,你可以使用这个:

IntStream.iterate(0, i -> i + 3)
        .limit(list.size() / 3)
        .mapToObj(list::get)
        .forEach(System.out::println);

编辑: 正如 Holger 在 cmets 中指出的那样,更有效的解决方案是:

IntStream.range(0, list.size() / 3)
        .mapToObj(i -> list.get(i * 3))
        .forEach(System.out::println);

【讨论】:

  • 更高效:IntStream.range(0, list.size()/3).mapToObj(i -&gt; list.get(i*3)) …
  • @Holger 为什么这样更有效率?
  • 它归结为一个内部计数循环,而不是一个评估两个不透明函数的循环。如果 JVM 设法内联它们,它们可以优化为相同的循环逻辑,但是当大小是可预测的时,Stream 实现对于某些操作的行为仍然不同(另请参阅here)。
【解决方案2】:

您必须使用 IntStream。

例如,以下将创建一个Stream,其中包含所有索引可被3整除的List元素:

List<String> yourList = ...
IntStream.range(0,yourList.size()) // IntStream of 0,1,2,3,...
         .filter(i -> i % 3 == 0) // IntStream of 0,3,6,...
         .mapToObj(yourList::get) // Stream<String> of yourList.get(0),yourList.get(3),...
         ...

【讨论】:

  • 当然,对于get 不能直接访问的任何列表(如LinkedList),这比在无聊的旧式中使用其迭代器循环遍历列表效率要低得多-老式的方式。但问题确实指定了流...(使用像 ArrayList 这样的直接访问列表,它只是效率较低,而不是显着效率降低。)
  • @T.J.Crowder 但没有理智的程序员会使用LinkedList。但是使用IntStream.range(0, list.size()/3).mapToObj(i -&gt; list.get(i*3)) … 会更有效,因为它避免了执行涉及模运算的list.size() 条件,并使流能够利用已知大小,例如用于终端操作toArraycount 或并行流。这已经比基于 Iterator 的循环更有效,并且可以在内联后优化到与计数循环相同的性能。
  • @Holger - LinkedList 有用途。只是不是当您需要 O(1) 访问时间时。
  • @T.J.Crowder 并且通常不适用于基于List 接口的任何算法(获取ListIterator 除外)。如果没有更好的选择,您很少会找到LinkedList 的用例。这不是关于链表的概念,而是这个特定的实现类作为 Java 集合框架的成员。
猜你喜欢
  • 2011-12-06
  • 2021-07-25
  • 1970-01-01
  • 2018-07-11
  • 2019-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-29
相关资源
最近更新 更多