问题描述
是否可以从迭代器创建一个Stream,其中对象序列与通过重复调用迭代器的next()方法生成的对象序列相同?我正在考虑的具体情况涉及使用TreeSet.descendingIterator()返回的迭代器,但我可以想象其他情况下迭代器,而不是它引用的集合是可用的。
Is it possible to create a Stream from an Iterator, in which the sequence of objects is the same as that generated by calling the iterator's next() method repeatedly? The specific case I am thinking of concerns the use of the iterator returned by TreeSet.descendingIterator(), but I can imagine other circumstances in which an iterator, but not the collection it references, is available.
例如,对于 TreeSet< T> tset
我们可以编写 tset.stream()...
并以集合的排序顺序获取该集合中的对象流,但是如果我们想要它们以不同的顺序,例如通过使用 descendingIterator()
获得的顺序,该怎么办?我想象的是像 tset.descendingIterator()。stream()...
或 stream(tset.descendingIterator())...
,但这些表格都不是有效的。
For example, for a TreeSet<T> tset
we can write tset.stream()...
and get a stream of the objects in that set, in the set's sort order, but what if we want them in a different order, such as that available through using descendingIterator()
? I am imagining something like tset.descendingIterator().stream()...
or stream( tset.descendingIterator() )...
, though neither of these forms are valid.
推荐答案
对于 NavigableSet.descendingIterator()
的特定示例,我认为最简单的方法是使用。
For the particular example of NavigableSet.descendingIterator()
, I think the simplest way is to use NavigableSet.descendingSet()
instead.
但鉴于你可能对更一般的情况感兴趣,以下似乎有效:
But given you are probably interested in the more general case, the following seems to work:
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<String> set = new TreeSet<>();
set.add("C");
set.add("A");
set.add("B");
Iterator<String> iterator = set.descendingIterator();
int characteristics = Spliterator.DISTINCT | Spliterator.SORTED | Spliterator.ORDERED;
Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(iterator, characteristics);
boolean parallel = false;
Stream<String> stream = StreamSupport.stream(spliterator, parallel);
stream.forEach(System.out::println); // prints C, then B, then A
}
}
In简而言之,您必须创建一个首先使用。然后,您可以使用。
In short, you have to create a Spliterator
from the Iterator
first using one of the static methods in Spliterators
. Then you can create a Stream
using the static methods in StreamSupport
.
我不喜欢手动创建Spliterators和Streams有很多经验,所以我无法评论它们的特征应该是什么或者它们会产生什么样的效果。在这个特别简单的例子中,我是否定义了如上所述的特征,或者我是否将其设置为0(即没有特征)似乎并不重要。在 Spliterators
中还有一个用于创建具有初始大小估计的Spliterator的方法 - 我想在这个特定的例子中你可以使用 set.size()
,但是如果你想处理任意迭代器,我想这不会是这种情况。同样,我不太确定它对性能的影响。
I don't have that much experience with creating Spliterators and Streams by hand yet, so I can't really comment on what the characteristics should be or what effect they will have. In this particular simple example, it didn't seem to matter whether I defined the characteristics as above, or whether I set it to 0 (i.e. no characteristics). There is also a method in Spliterators
for creating a Spliterator with an initial size estimate - I suppose in this particular example you could use set.size()
, but if you want to handle arbitrary Iterators I guess this won't be the case. Again, I'm not quite sure what effect it has on performance.
这篇关于如何从迭代器创建Java 8流?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!