2017-02-24 17 views
1

streamの別のアクションに問題があります。Stringです。Java 8 - 文字列のストリーム上で区別 - IllegalStateException

Stream<String> names = Arrays.asList("NAME A", "NAME B", "NAME A").stream(); 
names.distinct(); 
System.out.println(names.collect(Collectors.joining(","))); 

その後、私は例外受け取っ:

Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed 
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:229) 
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) 
at com.Test.main(Test.java:62) 

をしかし、私はこのようなコードのこの部分を書いた場合:

Stream<String> names = Arrays.asList("NAME A", "NAME B", "NAME A").stream(); 
final Stream<String> distinct = names.distinct(); 
System.out.println(distinct.collect(Collectors.joining(","))); 

すべてがOKです。このストリームの別個の要素(はObject.equalsに係る(オブジェクト))からなるストリームを返し

異なるストリーム():別個の

ドキュメント言います。 順序付けられたストリームの場合、別個の要素の選択は安定しています(重複した要素の場合、エンカウンター順で最初に出現する要素は保持されます)。 これはステートフルな中間操作です。

私は間違っていますか?

ありがとうございます。

+0

@choasia、慎重にお読みください – MateuszW90

+1

中間操作で生成された新しいストリームを無視し、1つのストリームを1回しか操作できないためですか? – choasia

答えて

4

ドキュメントとエラーメッセージがあなたに理由を与えるだろう。しかし、collectnamesにもう一度。しかし、このストリームはすでにdistinctオペレータによって消費されていました。

別のストリームを収集するため、2番目の例では、正しく入力してください。

だから、基本的に、あなたは常にthe documentationが言うように、あなたの第二の例のように、あるいは短い

names.distinct().collect(Collectors.joining(",")); 
4

基本的にストリームAPIを間違って使用しています。

あなたがしてはならないdistinct()の戻り値を無視しています。これはパラメータで直接動作しないメソッドと似ていますが、変更されたバージョンを返します。異なる要素を持つ新しいストリームを返しstream has already been operated upon or closeddistinct() Returns a stream

あなたはnamesdistinctを呼び出すと、それは:

慣用バージョンが

String names = Arrays.asList("NAME A", "NAME B", "NAME A"). 
    stream().distinct().collect(Collectors.joining(","); 
System.out.println(names); 
3

でそれをしなければならない。

ストリームは中間かを呼び出す(上で動作する必要がありますターミナルストリーム操作)を1回だけ実行します。これは、例えば、同じソースが2つ以上のパイプラインを供給する「フォークされた」ストリーム、または同じストリームの複数のトラバースを排除します。ストリームが再利用されていることが検出された場合、ストリーム実装はIllegalStateExceptionをスローする可能性があります。

ストリームでdistinct()を呼び出した後は、もう一度使用しないでください。代わりに、返されたストリームを使用します。操作をsource.stream().intermediateOp().anotherIntermediateOp().terminalOp()の形式で連鎖させると、このエラーは決して発生しません。


は、だからあなたの場合には、それが

String s = Arrays.asList("NAME A", "NAME B", "NAME A").stream() 
     .distinct().collect(Collectors.joining(",")); 
System.out.println(s); 

だろうが、あなたの代わりにArrays.asListを使用してのストレートフォワード

String s = Stream.of("NAME A", "NAME B", "NAME A") 
     .distinct().collect(Collectors.joining(",")); 
System.out.println(s); 

を使用することができます。

関連する問題