如何在下面的代码中获取流或列表的最后一个元素?
在哪里data.careas
是一个List
CArea first = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal).findFirst().get();
CArea last = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.collect(Collectors.toList()).; //how to?正如您所看到的,使用某个元素来获取第一个元素filter
,并不难。
然而,获取一行代码中的最后一个元素是一件非常痛苦的事情:
似乎我不能直接从Stream
..。(它只对有限的流有意义)
看起来你也不能得到像这样的东西first()
和last()
从List
接口,这真的很痛苦。
我看不出有任何理由不提供first()
和last()
方法中的List
接口中的元素是有序的,而且大小是已知的。
但根据最初的答案:如何获取有限元的最后一个元素
就我个人而言,这是我能得到的最接近的结果:
int lastIndex = data.careas.stream()
.filter(c -> c.bbox.orientationHorizontal)
.mapToInt(c -> data.careas.indexOf(c)).max().getAsInt();
CArea last = data.careas.get(lastIndex);但是,它确实涉及到使用indexOf
在每个元素上,这很可能不是您通常想要的,因为它可能会影响性能。
发布于 2014-01-30 04:13:05
可以使用方法获取最后一个元素流Stream::reduce.下面的清单包含一般情况的最小示例:
Stream stream = ...; // sequential or parallel stream
Optional last = stream.reduce((first, second) -> second);此实现适用于所有人ordered streams(包括从以下位置创建的Lists)。对于unorderedstreams由于明显的原因,未指定将返回哪个元素。该实现对这两种情况都有效。顺序和并行流。乍一看,这可能会令人惊讶,但不幸的是,文档并没有明确说明这一点。然而,这是streams的一个重要特性,我试着澄清一下:
Stream::reduce方法的 Javadoc 指出,它“不受限于顺序执行”。 Javadoc 还要求“累加器函数必须是用于组合两个值的关联的、无干扰的、无状态的函数”,这显然是 lambda 表达式 (first, second) -> second 的情况。reduction operations Javadoc 声明:“流类有多种形式的通用归约操作,称为 reduce()
和collect() [..]”和“一个正确构造的归约操作本质上是可并行化的,只要函数) 用于处理元素是的associative和stateless."的。
” 密切相关Collectors的文档更加明确:“为了确保顺序和并行执行产生等效的结果,收集器函数必须满足associativity和关联性约束。”
回到最初的问题:下面的代码在变量 last中存储了对最后一个元素的引用,如果流为空则抛出异常。复杂度与流的长度呈线性关系。
CArea last = data.careas
.stream()
.filter(c -> c.bbox.orientationHorizontal)
.reduce((first, second) -> second).get();发布于 2015-10-07 15:34:54
如果你有一个Collection (或者更通用的Iterable),你可以使用Google Guava
Iterables.getLast(myIterable)就像一个很好用的眼线笔。
发布于 2019-05-08 02:24:36
对于这种情况,Guava有专门的方法:
Stream stream = ...;
Optional lastItem = Streams.findLast(stream);它相当于stream.reduce((a, b) -> b)但创建者声称它的性能要好得多。
From documentation:
来自文档此方法的运行时间将介于O(log )和O(n)之间,在高效可拆分的流上执行得更好。
值得一提的是,如果流是无序的,则此方法的行为类似于findAny()。
https://stackoverflow.com/questions/21426843
复制相似问题