Paw*_*lov 18 java java-8 java-stream
是否有一种理智的方式从列表中获取有序流(具体来说,数组列表,但它应该无关紧要)流式元素与它们在原始列表中的方式相反?
我正在寻找一种不涉及缓冲数据的解决方案(收集器,另一个列表,数组等,因为它们复制了浪费的容器),或者使用Collections.reverse(因为它修改了列表).
到目前为止,我在这里看到的最干净的方法之一是实现我自己的版本的Spliterator这ORDERED和在列表中反向前进,或实施Iterator反向迭代是,并使用Spliterators.spliteratorUnknownSize(iterator,ORDERED)它.
注意这个问题不同于Java 8流逆序:其他问题询问如何反转流(一般情况下这是不可能的),并且答案提供了以某种方式反转源(我不想这样做),然后传输反向源.逆转源的成本是O(N),如果可能的话我想完全避免它.
Hol*_*ger 19
如果您List是随机访问列表,则可以使用
int num=list.size()-1;
IntStream.rangeClosed(0, num).mapToObj(i->list.get(num-i))
Run Code Online (Sandbox Code Playgroud)
创造一个Stream具有特征ORDERED | SIZED | SUBSIZED并提供完全分裂支持的东西.
LinkedList然而,对于非随机访问列表来说,这将是一场性能灾难,无论如何都会使用LinkedList?
您也可以先通过list instanceofRandomAccess... 查询
注意:如果您有一个ArrayList或其他列表允许通过index(get(i))进行随机访问检索,那么Holger的方法更可取.如果您的数据结构允许反向遍历但不允许索引访问,则只需要以下方法.
不幸的是,似乎没有一种非常简单的方法(即单线程)来做到这一点.但是,使用反向流AbstractSpliterator并不太困难,因为List已经具有反向迭代的能力.这是一个实用方法:
static <T> Stream<T> reversedStream(List<? extends T> input) {
ListIterator<? extends T> li = input.listIterator(input.size());
return StreamSupport.stream(
new Spliterators.AbstractSpliterator<T>(input.size(), Spliterator.ORDERED) {
@Override public boolean tryAdvance(Consumer<? super T> action) {
if (li.hasPrevious()) {
action.accept(li.previous());
return true;
} else {
return false;
}
}
},
false);
}
Run Code Online (Sandbox Code Playgroud)
(我想Spliterator可能是SIZED,但这是毫无意义的,因为这是一个不可分割的分裂器.)
就目前而言,这可以提供有限程度的并行性,因为AbstractSpliterator它将调用tryAdvance多次并批量处理以交付到fork-join任务.但它没有能够分裂的效率.
如果并行效率是一个很大的问题,那么可以编写一个可以实际拆分的分裂器,其中拆分以相反的顺序遍历.
从 Java 21 开始,该reversed()方法可用于返回列表上的反向视图,然后可以对其进行流式传输:
Stream<Object> reversedStream = list.reversed().stream();
Run Code Online (Sandbox Code Playgroud)
根据要求,这不会缓冲或复制数据,因为这只是原始列表的反向视图。
Google 的 Guava 库提供了列表的反向视图 ( Lists#reverse(List))。ReverseListIteratorApache Commons Collection 库中也有一个。
小智 5
我最近找到了这个解决方案。
public <T> Stream<T> toReverseStream(List<T> list) {
ListIterator<T> listIterator = list.listIterator(list.size());
return Stream.generate(listIterator::previous)
.limit(list.size());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12343 次 |
| 最近记录: |