2016-03-28 120 views
24

我正在学习新的Java 8功能,并在尝试使用流(java.util.stream.Stream)和收集器时,我意识到一个流不能使用两次..有什么方法可以重用它吗?有没有什么方法可以重用java 8中的Stream?

+0

是,流可以被重复使用,只有当任何用途都不会在其上调用任何终端操作。 –

+0

[Copy a stream to avoid“stream has been been been upon upon or closed”(java 8)](http://stackoverflow.com/questions/23860533/copy-a-stream-to-avoid-stream- has-been-been-operated-upon-or-closed-java-8) – Andrejs

回答

32

documentation

甲流应在(调用的中间或末端流操作)只有一次操作。

如果流实现检测到流正在被重用,则可能会抛出IllegalStateException。

所以答案是否定的,流不意味着被重用。

1

流的整个想法是它是一次性的。这使您可以创建不可重新获取的来源(例如,从网络连接读取线路)而无需中间存储。如果,但是,要重用流的内容,你可以转储到中间收集获得“硬拷贝”:

Stream<MyType> stream = // get the stream from somewhere 
List<MyType> list = stream.collect(Collectors.toList()); // materialize the stream contents 
list.stream().doSomething // create a new stream from the list 
list.stream().doSomethingElse // create one more stream from the list 

如果你不想兑现流,在某些情况下,是同时使用同一个流做几件事的方法。例如,有关详细信息,请参阅thisthis问题。

23

如果您想要重新使用流的效果,可以将流表达式包装到供应商中,并在需要时重新调用myStreamSupplier.get()。例如,

Supplier<Stream<String>> sup =() -> 
     someList.stream(); 
List<String> nonEmptyStrings = sup.get().filter(s -> !s.isEmpty()).collect(Collectors.toList()); 
Set<String> uniqueStrings = sup.get().collect(Collectors.toSet()); 
+1

这不会重用流。供应商只是在每次调用时创建一个新的流。 – axiopisty

+5

这就是为什么汉克D说“效果”。它仍然是更清洁,更可重用的代码。 – Andrejs

9

正如其他人所说,“不,你不能”。

但要记住很多基本操作方便summaryStatistics()这是有用的:

所以不是:

List<Person> personList = getPersons(); 

personList.stream().mapToInt(p -> p.getAge()).average().getAsDouble(); 
personList.stream().mapToInt(p -> p.getAge()).min().getAsInt(); 
personList.stream().mapToInt(p -> p.getAge()).max().getAsInt(); 

您可以:

// Can also be DoubleSummaryStatistics from mapToDouble() 

IntSummaryStatistics stats = personList.stream() 
             .mapToInt(p-> p.getAge()) 
             .summaryStatistics(); 

stats.getAverage(); 
stats.getMin(); 
stats.getMax(); 
相关问题