ジョシュ:
私はすべての文字列から文字列の順列を返すようにしたいと思います。私はコードの下に使用する場合は、私が得ますjava.lang.IllegalStateException: stream has already been operated upon or closed
。あなたは、このアプローチが間違っているものを私に教えていただけますか?
public Stream<String> getMyPatterns(
Stream<String> s1,
Stream<String> s2,
Stream<String> s3) {
List<String> out = new ArrayList<String>();
s1.collect(Collectors.toList()).forEach(item1 -> {
s2.collect(Collectors.toList()).forEach(item2 -> {
s3.collect(Collectors.toList()).forEach(item3 -> {
out.add(item1 + "." + item2 + "." + item3);
});
});
});
return out.stream();
}
サンプルテスト
Stream<String> patterns = getMyPatterns(
Stream.of("a1", "a2"),
Stream.of("b1", "b2"),
Stream.of("c1", "c2"));
ホルガー:
他の人が示唆したとして、あなたは、Streamsを使用しているs2
とs3
の範囲内forEach
で複数回。
一方、ストリームを返す前に、結果のリストを収集し、無意味です。あなたは使用しないでくださいforEach
他の、より適切な操作がある場合には、とにかく。
あなただけが前のものと組み合わせたいストリームを収集する必要があります。これは、最高の最初の二つの流れの組み合わせのためにそれを解くことによって実現されます。
public Stream<String> getMyPatterns(Stream<String> s1, Stream<String> s2) {
List<String> s2List = s2.collect(Collectors.toList());
return s1.flatMap(item1 -> s2List.stream().map(item2 -> item1+'.'+item2));
}
その後、あなたは簡単に3つのストリームを組み合わせるの課題を解決するために、再帰的に、このメソッドを使用することができます。
public Stream<String> getMyPatterns(Stream<String> s1,Stream<String> s2,Stream<String> s3) {
return getMyPatterns(getMyPatterns(s1, s2), s3);
}
この収集にのみ必要な限り少なく、つまりはそれがない収集する最初のストリーム、返されたストリームが消費されると、その消費量はのみを開始しますので。
Stream<String> patterns = getMyPatterns(
Stream.of("a1", "a2").peek(s -> System.out.println("consuming "+s)),
Stream.of("b1", "b2"),
Stream.of("c1", "c2"));
System.out.println("start consuming result Stream");
System.out.println(patterns.collect(Collectors.joining(", ")));
start consuming result Stream
consuming a1
consuming a2
a1.b1.c1, a1.b1.c2, a1.b2.c1, a1.b2.c2, a2.b1.c1, a2.b1.c2, a2.b2.c1, a2.b2.c2