Reputation: 33
I want to find out String
s starting with a particular character using the same Stream
twice, but the second Stream
operation is throwing an exception. How can I re-use the 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
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)
Upvotes: 1
Views: 368
Reputation: 9633
when you call any terminal operation the stream is closed, You could use stream supplier to construct a new stream
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);
Upvotes: 0
Reputation: 113
Use a logic OR to combine your streams into only one stream:
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);
}
Upvotes: 1
Reputation: 393821
You can't perform a terminal operation such as forEach
twice on the same Stream
.
You have other alternatives. For example, you can produce a Map<Character,List<String>>
in which the input String
s are grouped by their first character :
Map<Character,List<String>> groups =
Stream.of("abc", "aef", "bcd", "bef", "crf")
.collect(Collectors.groupingBy(s->s.charAt(0)));
This will result in the following Map
:
{a=[abc, aef], b=[bcd, bef], c=[crf]}
Upvotes: 2