Java 嵌套流异常
我想返回所有字符串的字符串排列。当我使用下面的代码时,我得到Java 嵌套流异常,java,java-8,java-stream,Java,Java 8,Java Stream,我想返回所有字符串的字符串排列。当我使用下面的代码时,我得到java.lang.IllegalStateException:流已经被操作或关闭了。你能告诉我这种方法有什么问题吗 public Stream<String> getMyPatterns( Stream<String> s1, Stream<String> s2, Stream<String> s3) { List<Strin
java.lang.IllegalStateException:流已经被操作或关闭了
。你能告诉我这种方法有什么问题吗
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();
}
公共流getMyPatterns(
溪流s1,
流s2,
流(s3){
List out=new ArrayList();
s1.collect(Collectors.toList()).forEach(item1->{
s2.collect(Collectors.toList()).forEach(item2->{
s3.collect(collector.toList()).forEach(item3->{
增加(项目1+“+项目2+”+项目3);
});
});
});
return out.stream();
}
样品试验
Stream<String> patterns = getMyPatterns(
Stream.of("a1", "a2"),
Stream.of("b1", "b2"),
Stream.of("c1", "c2"));
Stream patterns=getMyPatterns(
“a1”、“a2”流,
“b1”、“b2”流,
(c1、c2)流;
流应该被消耗或操作一次,但在您的解决方案中,您可以在一个循环中多次消耗它,相反,您可以这样解决您的问题:
public static Stream<String> getMyPatterns(Stream<String> s1, Stream<String> s2, Stream<String> s3) {
List<String> out = new ArrayList<String>();
List<String> c1 = s1.collect(Collectors.toList());
List<String> c2 = s2.collect(Collectors.toList());
List<String> c3 = s3.collect(Collectors.toList());
c1.forEach(item1 -> {
c2.forEach(item2 -> {
c3.forEach(item3 -> {
out.add(item1 + "." + item2 + "." + item3);
});
});
});
return out.stream();
}
公共静态流getMyPatterns(流s1、流s2、流s3){
List out=new ArrayList();
列表c1=s1.collect(Collectors.toList());
List c2=s2.collect(Collectors.toList());
List c3=s3.collect(Collectors.toList());
c1.forEach(第1项->{
c2.forEach(第2项->{
c3.forEach(第3项->{
增加(项目1+“+项目2+”+项目3);
});
});
});
return out.stream();
}
流只能使用或操作一次
public static Stream<String> getMyPatterns(
Stream<String> s1,
Stream<String> s2,
Stream<String> s3) {
List<String> c1 = s1.collect(Collectors.toList());
List<String> c2 = s2.collect(Collectors.toList());
List<String> c3 = s3.collect(Collectors.toList());
BiFunction<String, Stream<String>, Stream<String>> func = (element, partialResultStream) -> partialResultStream.map(x -> x + "." + element);
return c1.stream().flatMap(x -> func.apply(x, c2.stream()))
.flatMap(x -> func.apply(x, c3.stream()));
}
公共静态流getMyPatterns(
溪流s1,
流s2,
流(s3){
列表c1=s1.collect(Collectors.toList());
List c2=s2.collect(Collectors.toList());
List c3=s3.collect(Collectors.toList());
双函数func=(元素,partialResultStream)->partialResultStream.map(x->x+“+元素);
返回c1.stream().flatMap(x->func.apply(x,c2.stream()))
.flatMap(x->funct.apply(x,c3.stream());
}
输出
[c1.b1.a1、c2.b1.a1、c1.b2.a1、c2.b2.a1、c1.b1.a2、c2.b1.a2、c1.b2.a2、c2.b2.a2、c2.b2.a2]
正如其他人所暗示的,您在
forEach
中多次使用流s2
和s3
另一方面,在返回流之前收集结果列表是没有意义的。当存在其他更合适的操作时,无论如何都不应该使用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));
}
您可以使用集合来实现这一点,然后将其转换为流以避免重用它们:
public static void main(String[] args) {
Stream<String> combine = combine(Arrays.asList("1", "2", "3"), Arrays.asList("4", "5", "6"), Arrays.asList("7", "8", "9"));
combine.forEach(System.out::println);
}
static Stream<String> combine(List<String> s1, List<String> s2, List<String> s3){
return s1.stream().flatMap(v1 ->
s2.stream().flatMap(v2 ->
s3.stream().flatMap(v3 -> Stream.of(v1 + "." + v2 + "." + v3 + ";"))
)
);
}
publicstaticvoidmain(字符串[]args){
Stream combine=combine(Arrays.asList(“1”、“2”、“3”)、Arrays.asList(“4”、“5”、“6”)、Arrays.asList(“7”、“8”、“9”);
combine.forEach(System.out::println);
}
静态流联合收割机(列表s1、列表s2、列表s3){
返回s1.stream().flatMap(v1->
s2.stream().flatMap(v2->
s3.stream().flatMap(v3->stream.of(v1+“+v2+”+“+v3+”;”))
)
);
}
提示:您可以运行s2。收集
不止一次您不能只传入流。您必须传入回调以生成新的流。希望我的回答有帮助
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(", ")));
public static void main(String[] args) {
Stream<String> combine = combine(Arrays.asList("1", "2", "3"), Arrays.asList("4", "5", "6"), Arrays.asList("7", "8", "9"));
combine.forEach(System.out::println);
}
static Stream<String> combine(List<String> s1, List<String> s2, List<String> s3){
return s1.stream().flatMap(v1 ->
s2.stream().flatMap(v2 ->
s3.stream().flatMap(v3 -> Stream.of(v1 + "." + v2 + "." + v3 + ";"))
)
);
}