ski*_*iwi 100 java list java-8 java-stream
如何在以下代码中获取流或列表的最后一个元素?
哪里data.careas
是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?
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样,获得第一个元素filter
并不难.
然而,获得单行中的最后一个元素是一个真正的痛苦:
Stream
.(它只对有限流有意义)first()
和last()
从List
接口,这实在是一种痛苦.我没有看到任何关于不在接口中提供first()
和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);
Run Code Online (Sandbox Code Playgroud)
然而,它确实涉及使用indexOf
每个元素,这很可能不是您通常想要的,因为它可能会影响性能.
nos*_*sid 167
可以使用Stream :: reduce方法获取最后一个元素.以下列表包含一般情况的最小示例:
Stream<T> stream = ...; // sequential or parallel stream
Optional<T> last = stream.reduce((first, second) -> second);
Run Code Online (Sandbox Code Playgroud)
此实现适用于所有有序流(包括从列表创建的流).对于无序流,由于显而易见的原因,未指定将返回哪个元素.
该实现适用于顺序和并行流.乍一看可能会令人惊讶,遗憾的是文档没有明确说明.但是,它是流的一个重要特征,我试着澄清它:
(first, second) -> second
.密切相关的收集器的文档更加明确:"为了确保顺序和并行执行产生相同的结果,收集器函数必须满足标识和关联约束."
回到原始问题:以下代码存储对变量中最后一个元素的引用,last
如果流为空则抛出异常.复杂度在流的长度上是线性的.
CArea last = data.careas
.stream()
.filter(c -> c.bbox.orientationHorizontal)
.reduce((first, second) -> second).get();
Run Code Online (Sandbox Code Playgroud)
Pet*_*eti 37
如果您有一个Collection(或更一般的Iterable),您可以使用Google Guava
Iterables.getLast(myIterable)
Run Code Online (Sandbox Code Playgroud)
作为方便的oneliner.
k13*_*13i 12
Guava 有专门的方法来处理这种情况:
Stream<T> stream = ...;
Optional<T> lastItem = Streams.findLast(stream);
Run Code Online (Sandbox Code Playgroud)
它相当于stream.reduce((a, b) -> b)
但创作者声称它具有更好的性能。
从文档:
此方法的运行时将介于 O(log n) 和 O(n) 之间,在高效可拆分流上表现更好。
值得一提的是,如果流是无序的,则此方法的行为类似于findAny()
.
一个班轮(不需要流;):
Object lastElement = list.get(list.size()-1);
Run Code Online (Sandbox Code Playgroud)
list.stream().sorted(Comparator.comparing(obj::getSequence).reversed()).findFirst().get();
Run Code Online (Sandbox Code Playgroud)
反转顺序并获取列表中的第一个元素。这里的对象有序列号,比较器提供了可以根据逻辑使用的多种功能。
归档时间: |
|
查看次数: |
71545 次 |
最近记录: |