如何将一个迭代器转换为一个stream?

我正在寻找一种简洁的方式来将Iterator转换为Stream或者更具体地说,将迭代器“查看”为stream。

出于性能的原因,我想避免在新列表中的迭代器的副本:

 Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator(); Collection<String> copyList = new ArrayList<String>(); sourceIterator.forEachRemaining(copyList::add); Stream<String> targetStream = copyList.stream(); 

根据评论中的一些build议,我也尝试使用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); } 

但是,我得到一个NoSuchElementException (因为没有调用hasNext

 Exception in thread "main" java.util.NoSuchElementException at java.util.AbstractList$Itr.next(AbstractList.java:364) at Main$$Lambda$1/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) 

我曾看过StreamSupportCollections但是我没有find任何东西。

5 Solutions collect form web for “如何将一个迭代器转换为一个stream?”

一种方法是从迭代器创build一个Spliterator,并将其用作stream的基础:

 Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator(); Stream<String> targetStream = StreamSupport.stream( Spliterators.spliteratorUnknownSize(sourceIterator, Spliterator.ORDERED), false); 

另一种更具可读性的方法是使用Iterable – 并且从Iterator创buildIterable对于lambdaexpression式非常简单,因为Iterable是一个function性接口:

 Iterator<String> sourceIterator = Arrays.asList("A", "B", "C").iterator(); Iterable<String> iterable = () -> sourceIterator; Stream<String> targetStream = StreamSupport.stream(iterable.spliterator(), false); 

伟大的build议! 这是我可重复使用的:

 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); } } 

和用法(确保静态导入asStream):

 List<String> aPrefixedStrings = asStream(sourceIterator) .filter(t -> t.startsWith("A")) .collect(toList()); 

自21版以来,番石榴图书馆提供

 Streams.stream(iterator) 

它做@assylias答案显示。

使用SpliteratorIterator创buildSpliterator类包含多个用于创buildspliterator的函数,例如,在这里使用的是将迭代器作为参数的StreamSupport ,然后使用StreamSupport创buildStream

 Spliterator<Model> spliterator = Spliterators.spliteratorUnknownSize( iterator, Spliterator.NONNULL); Stream<Model> stream = StreamSupport.stream(spliterator, false); 

您可以使用迭代器简单地使用限制函数:

 Stream.generate(iterator::next).limit(list.size()) 
  • Java 8中的map和flatMap方法有什么区别?
  • 为什么这个Java 8 lambda无法编译?
  • 为什么Collections.sort使用Mergesort但Arrays.sort不?
  • ::(双冒号)运算符在Java 8中
  • 如何将java.sql.timestamp转换为LocalDate(java8)java.time?
  • 有没有一个简洁的方式来迭代在Java 8中的索引stream?
  • 使用Lambdas将列表列表变成列表
  • 将Java未来转化为CompletableFuture
  • 如何在Java8中为void(不是Void)方法指定函数types?
  • .collect是否保证在并行stream上sorting?
  • Java 8不同属性