2016-03-28 167 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(); 
相關問題