jos*_*osh 2 java java-8 java-stream
我想返回所有字符串的字符串排列。当我使用下面的代码时,我得到了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();
}
Run Code Online (Sandbox Code Playgroud)
样品测试
Stream<String> patterns = getMyPatterns(
Stream.of("a1", "a2"),
Stream.of("b1", "b2"),
Stream.of("c1", "c2"));
Run Code Online (Sandbox Code Playgroud)
作为暗示别人,您使用的是流s2
和s3
内forEach
多次。
另一方面,在返回Stream之前收集结果列表是没有意义的。forEach
无论如何,如果还有其他更合适的操作,则不应该使用。
您只需要收集要与上一个合并的Stream。最好首先解决两个流的组合来实现:
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));
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以轻松地递归使用此方法来解决合并三个Streams的任务:
public Stream<String> getMyPatterns(Stream<String> s1,Stream<String> s2,Stream<String> s3) {
return getMyPatterns(getMyPatterns(s1, s2), s3);
}
Run Code Online (Sandbox Code Playgroud)
这只会收集尽可能少的内容,即不会收集第一个Stream,因此只有在消耗返回的Stream时才开始消耗它。
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(", ")));
Run Code Online (Sandbox Code Playgroud)
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));
}
Run Code Online (Sandbox Code Playgroud)