我希望使用相同的String
两次找出以特定字符开头的Stream
,但第二个Stream
操作会抛出异常。如何重新使用Stream
?
public static void main(String[] args) {
Stream<String> stream = Stream.of("abc", "aef", "bcd", "bef", "crf");
stream.filter(s -> s.startsWith("a")).forEach(System.out::println);;
stream.filter(s -> s.startsWith("b")).forEach(System.out::println);;
}
异常
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.<init>(Unknown Source)
at java.util.stream.ReferencePipeline.<init>(Unknown Source)
at java.util.stream.ReferencePipeline$StatelessOp.<init>(Unknown Source)
at java.util.stream.ReferencePipeline$2.<init>(Unknown Source)
at java.util.stream.ReferencePipeline.filter(Unknown Source)
at StreamExp.main(StreamExp.java:13)
答案 0 :(得分:2)
您无法在同一forEach
两次执行Stream
等终端操作。
您还有其他选择。例如,您可以生成Map<Character,List<String>>
,其中输入String
按其第一个字符分组:
Map<Character,List<String>> groups =
Stream.of("abc", "aef", "bcd", "bef", "crf")
.collect(Collectors.groupingBy(s->s.charAt(0)));
这将产生以下Map
:
{a=[abc, aef], b=[bcd, bef], c=[crf]}
答案 1 :(得分:1)
使用逻辑OR将流组合成一个流:
public static void main(String[] args) {
Stream<String> stream = Stream.of("abc", "aef", "bcd", "bef", "crf");
stream.filter(s -> s.startsWith("a") || s.startsWith("b")).forEach(System.out::println);
}
答案 2 :(得分:0)
当您呼叫任何终端操作时,流已关闭,您可以使用流供应商构建新流
Supplier<Stream<String>> streamSupplier =
() -> Stream.of("abc", "aef", "bcd", "bef", "crf");
streamSupplier.get().filter(s -> s.startsWith("a")).forEach(System.out::println);
streamSupplier.get().filter(s -> s.startsWith("b")).forEach(System.out::println);