2016-03-28 13 views
24

私は新しいJava 8の機能を学習しています。ストリーム(java.util.stream.Stream)とコレクターを試しているうちに、ストリームを2回使用できないことに気付きました。それを再利用する方法はありますか? documentationJava 8でStreamを再利用する方法はありますか?

から
+0

はい、ストリームがいる場合にのみ、再利用することができますいずれの用途でも端末操作を呼び出さない。 –

+0

[ストリームが既に操作されているか閉じているのを避けるためにストリームをコピーする](java 8)](http://stackoverflow.com/questions/23860533/copy-a-stream-to-avoid-stream- has-already-been-been-been-operated-on-closed-java-8) – Andrejs

答えて

32

ストリームは、一度だけ(中間または末端ストリームの操作を呼び出す)に操作されなければなりません。

ストリームの再利用が検出された場合、ストリームの実装によって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 

:あなたは、しかし、ストリームのコンテンツを再利用したい場合は、「ハードコピー」を取得するために中間コレクションにそれをダンプします一度に同じストリームでいくつかのことを行う方法です。たとえば、thisまたはthis質問を参照してください。

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(); 
関連する問題