Java 如何将迭代器转换为流?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24511052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert an iterator to a stream?
提问by gontard
I am looking for a concise way to convert an Iterator
to a Stream
or more specifically to "view" the iterator as a stream.
我正在寻找一种简洁的方法将 an 转换Iterator
为 aStream
或更具体地将迭代器“查看”为流。
For performance reason, I would like to avoid a copy of the iterator in a new list:
出于性能原因,我想避免在新列表中复制迭代器:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Collection<String> copyList = new ArrayList<String>();
sourceIterator.forEachRemaining(copyList::add);
Stream<String> targetStream = copyList.stream();
Based on the some suggestions in the comments, I have also tried to use Stream.generate
:
根据评论中的一些建议,我也尝试使用Stream.generate
:
public static void main(String[] args) throws Exception {
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream = Stream.generate(sourceIterator::next);
targetStream.forEach(System.out::println);
}
However, I get a NoSuchElementException
(since there is no invocation of hasNext
)
但是,我得到了一个NoSuchElementException
(因为没有调用hasNext
)
Exception in thread "main" java.util.NoSuchElementException
at java.util.AbstractList$Itr.next(AbstractList.java:364)
at Main$$Lambda/1175962212.get(Unknown Source)
at java.util.stream.StreamSpliterators$InfiniteSupplyingSpliterator$OfRef.tryAdvance(StreamSpliterators.java:1351)
at java.util.Spliterator.forEachRemaining(Spliterator.java:326)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at Main.main(Main.java:20)
I have looked at StreamSupport
and Collections
but I didn't find anything.
我已经看过了StreamSupport
,Collections
但我什么也没找到。
采纳答案by assylias
One way is to create a Spliterator from the Iterator and use that as a basis for your stream:
一种方法是从 Iterator 创建一个 Spliterator 并将其用作流的基础:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Stream<String> targetStream = StreamSupport.stream(
Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED),
false);
An alternative which is maybe more readable is to use an Iterable - and creating an Iterable from an Iterator is very easy with lambdas because Iterable is a functional interface:
另一种可能更具可读性的替代方法是使用 Iterable - 使用 lambdas 从 Iterator 创建 Iterable 非常容易,因为 Iterable 是一个功能接口:
Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator();
Iterable<String> iterable = () -> sourceIterator;
Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false);
回答by Matan
Great suggestion! Here's my reusable take on it:
很棒的建议!这是我对它的可重复使用的看法:
public class StreamUtils {
public static <T> Stream<T> asStream(Iterator<T> sourceIterator) {
return asStream(sourceIterator, false);
}
public static <T> Stream<T> asStream(Iterator<T> sourceIterator, boolean parallel) {
Iterable<T> iterable = () -> sourceIterator;
return StreamSupport.stream(iterable.spliterator(), parallel);
}
}
And usage (make sure to statically import asStream):
和用法(确保静态导入 asStream):
List<String> aPrefixedStrings = asStream(sourceIterator)
.filter(t -> t.startsWith("A"))
.collect(toList());
回答by Bassem Reda Zohdy
Create Spliterator
from Iterator
using Spliterators
class contains more than one function for creating spliterator, for example here am using spliteratorUnknownSize
which is getting iterator as parameter, then create Stream using StreamSupport
Create Spliterator
from Iterator
using Spliterators
class 包含多个用于创建 spliterator 的函数,例如这里使用的spliteratorUnknownSize
是获取迭代器作为参数,然后使用创建流StreamSupport
Spliterator<Model> spliterator = Spliterators.spliteratorUnknownSize(
iterator, Spliterator.NONNULL);
Stream<Model> stream = StreamSupport.stream(spliterator, false);
回答by numéro6
Since version 21, Guava library provides Streams.stream(iterator)
从版本 21 开始,Guava 库提供 Streams.stream(iterator)
It does what @assylias's answer shows.
回答by Israel C. S. Rocha
Use Collections.list(iterator).stream()...
用 Collections.list(iterator).stream()...
回答by PhilipRoman
This is possible in Java 9.
这在 Java 9 中是可能的。
Stream.generate(() -> null)
.takeWhile(x -> iterator.hasNext())
.map(n -> iterator.next())
.forEach(System.out::println);
回答by sneha
import com.google.common.collect.Streams;
and use Streams.stream(iterator)
:
并使用Streams.stream(iterator)
:
Streams.stream(iterator)
.map(v-> function(v))
.collect(Collectors.toList());