如何在以下代码中获取流或列表的最后一个元素?
Where data.careas
is a List<CArea>
:
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()
and last()
来自List
界面,这确实是一个痛苦。
我认为没有任何理由不提供first()
and last()
方法中的List
接口,因为其中的元素是有序的,而且大小是已知的。
但根据原来的答案:如何获得有限的最后一个元素Stream
?
就我个人而言,这是我能得到的最接近的:
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
在每个元素上,这很可能不是您通常想要的,因为它会损害性能。
可以使用该方法获取最后一个元素流::减少 http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-java.util.function.BinaryOperator-。以下清单包含一般情况的最小示例:
Stream<T> stream = ...; // sequential or parallel stream
Optional<T> last = stream.reduce((first, second) -> second);
此实现适用于所有人有序流 http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#Ordering(包括从创建的流Lists http://docs.oracle.com/javase/8/docs/api/java/util/List.html). For 无序的 http://docs.oracle.com/javase/8/docs/api/java/util/stream/BaseStream.html#unordered--由于明显的原因,streams 未指定将返回哪个元素。
该实施适用于两者顺序的 and 并行流。乍一看这可能会令人惊讶,不幸的是文档没有明确说明。然而,这是流的一个重要特征,我试图澄清它:
- 该方法的 Javadoc流::减少 http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-java.util.function.BinaryOperator-指出,它"is not被迫执行依次地".
- Javadoc 还要求“累加器函数必须是联想性的, 互不干扰, 无国籍的组合两个值的函数",这显然是 lambda 表达式的情况
(first, second) -> second
.
- Javadoc 的还原操作 http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#Reduction状态:“流类有多种形式的一般归约操作,称为reduce() http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-java.util.function.BinaryOperator- and 收集() http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.stream.Collector- [..]" and “正确构建的归约操作是本质上可并行,只要用于处理元素的函数是联想性的 http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#Associativity and 无国籍的 http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#NonInterfering."
密切相关的文档收藏家 http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.html更明确的是:“为了保证顺序的 and 并行执行生产同等结果,收集器函数必须满足恒等式和关联性 http://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#Associativity限制。”
回到最初的问题:以下代码存储对变量中最后一个元素的引用last
如果流为空,则抛出异常。复杂度与流的长度成线性关系。
CArea last = data.careas
.stream()
.filter(c -> c.bbox.orientationHorizontal)
.reduce((first, second) -> second).get();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)