如何从迭代器创建Java 8流?

是否可以从迭代器创建一个Stream,其中对象序列与通过重复调用迭代器的next()方法生成的对象序列相同? 我正在考虑的具体情况涉及使用TreeSet.descendingIterator()返回的迭代器,但我可以想象其他情况下迭代器,而不是它引用的集合是可用的。

例如,对于TreeSet tset我们可以编写tset.stream()...并以集合的排序顺序获取该集合中的对象流,但是如果我们希望它们以不同的顺序,例如可以通过使用descendingIterator()吗? 我想像tset.descendingIterator().stream()...stream( tset.descendingIterator() )... ,虽然这些forms都不是有效的。

对于NavigableSet.descendingIterator()的特定示例,我认为最简单的方法是使用NavigableSet.descendingSet()

但鉴于您可能对更一般的情况感兴趣,以下似乎有效:

 import java.util.Iterator; import java.util.Spliterator; import java.util.Spliterators; import java.util.TreeSet; import java.util.stream.Stream; import java.util.stream.StreamSupport; public class Streams { public static void main(String... args) { TreeSet set = new TreeSet<>(); set.add("C"); set.add("A"); set.add("B"); Iterator iterator = set.descendingIterator(); int characteristics = Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED; Spliterator spliterator = Spliterators.spliteratorUnknownSize(iterator, characteristics); boolean parallel = false; Stream stream = StreamSupport.stream(spliterator, parallel); stream.forEach(System.out::println); // prints C, then B, then A } } 

简而言之,您必须首先使用Spliterator中的一种静态方法从Iterator创建Spliterators 。 然后,您可以使用StreamSupport的静态方法创建Stream

我手动创建Spliterators和Streams没有那么多经验,所以我无法评论它们的特征应该是什么或它们会产生什么样的影响。 在这个特别简单的例子中,我是否定义了上述特征,或者我是否将其设置为0(即没有特征)似乎并不重要。 Spliterators还有一个方法用于创建具有初始大小估计的Spliterator – 我想在这个特定的例子中你可以使用set.size() ,但是如果你想处理任意迭代器,我想这不会是这种情况。 同样,我不太确定它对性能的影响。

 static  Stream iteratorToFiniteStream(final Iterator iterator) { return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false); } static  Stream iteratorToInfiniteStream(final Iterator iterator) { return Stream.generate(iterator::next); } 

这不会创建流​​,但Iterator也有一个名为forEachRemaining的方法:

 someIterator.forEachRemaining(System.out::println); someIterator.forEachRemaining(s -> s.doSomething()); //etc. 

您传入的参数是Consumer ,它与您传递给Stream :: forEach的内容相同 。

以下是该方法的文档 。 请注意, 您不能像流一样继续使用“链” 。 但我仍然发现这很有用,我想要一个Iterator的Stream。