I am new to Java 8 and looking to understand the difference between the two scenarios. I know that once a stream is operated and consumed then stream cant be reused again it will give an error.
Scenario-1:
List<String> title = Arrays.asList("Java8", "In", "Action");
Stream<String> s = title.stream();
s.forEach(System.out::println);
s.forEach(System.out::println); // THIS WILL GIVE ERROR - streams has been already operated and closed.
When I run this, I get below error... which is fair.
Java8
In
Action
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
at java.util.stream.AbstractPipeline.sourceStageSpliterator(Unknown Source)
at java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
at com.test.Java8InAction.CH4.TraversableOnlyOnce.main(TraversableOnlyOnce.java:12)
Scenario-2:
// Filtering unique elements
List<Integer> numbers = Arrays.asList(1, 2, 1, 3, 3, 2, 4);
numbers.stream().forEach(System.out::println);
numbers.stream().filter(n -> n % 2 == 0).distinct().forEach(System.out::println);
numbers.stream().filter(n -> n % 2 == 0).forEach(System.out::println);
Here also I have operated stream and closed the terminal operation, then why I did not get any error?
A stream should be operated on (invoking an intermediate or terminal stream operation) only once. This rules out, for example, "forked" streams, where the same source feeds two or more pipelines, or multiple traversals of the same stream.
A Stream should be operated on (invoking an intermediate or terminal stream operation) only once. A Stream implementation may throw IllegalStateException if it detects that the Stream is being reused. Whenever a terminal operation is called on a Stream object, the instance gets consumed and closed.
No. Java streams, once consumed, can not be reused by default. As Java docs say clearly, “A stream should be operated on (invoking an intermediate or terminal stream operation) only once.
Streams are lazy because intermediate operations are not evaluated until terminal operation is invoked. Each intermediate operation creates a new stream, stores the provided operation/function and return the new stream. The pipeline accumulates these newly created streams.
Because a stream can be consumed only once. if you want to use multiple time use Supplier for this.
Supplier<Stream<String>> streamSupplier = ()-> Stream.of("Java8", "In", "Action");
then use get
to create a new stream.
streamSupplier.get().forEach(System.out::println);
but in second scenario you create a new stream every time.
.stream()
creates a new instance of a Stream
despite the fact it's called on the same collection
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With