获取流最后一个元素的最有效方法
2022-08-31 12:41:45
流没有方法:last()
Stream<T> stream;
T last = stream.last(); // No such method
获取最后一个元素(或空流为空)的最优雅和/或最有效的方法是什么?
流没有方法:last()
Stream<T> stream;
T last = stream.last(); // No such method
获取最后一个元素(或空流为空)的最优雅和/或最有效的方法是什么?
执行一个仅返回当前值的缩减:
Stream<T> stream;
T last = stream.reduce((a, b) -> b).orElse(null);
这在很大程度上取决于 的性质。请记住,“简单”并不一定意味着“高效”。如果您怀疑流非常大,承载了繁重的操作或具有事先知道大小的源,则以下方法可能比简单的解决方案更有效:Stream
static <T> T getLast(Stream<T> stream) {
Spliterator<T> sp=stream.spliterator();
if(sp.hasCharacteristics(Spliterator.SIZED|Spliterator.SUBSIZED)) {
for(;;) {
Spliterator<T> part=sp.trySplit();
if(part==null) break;
if(sp.getExactSizeIfKnown()==0) {
sp=part;
break;
}
}
}
T value=null;
for(Iterator<T> it=recursive(sp); it.hasNext(); )
value=it.next();
return value;
}
private static <T> Iterator<T> recursive(Spliterator<T> sp) {
Spliterator<T> prev=sp.trySplit();
if(prev==null) return Spliterators.iterator(sp);
Iterator<T> it=recursive(sp);
if(it!=null && it.hasNext()) return it;
return recursive(prev);
}
您可以使用以下示例来说明差异:
String s=getLast(
IntStream.range(0, 10_000_000).mapToObj(i-> {
System.out.println("potential heavy operation on "+i);
return String.valueOf(i);
}).parallel()
);
System.out.println(s);
它将打印:
potential heavy operation on 9999999
9999999
换句话说,它没有对前9999999个元素执行操作,而只对最后一个元素执行操作。