Java 8 - Once Stream is consumed and operated giving error, but in another case its not

stream has already been operated upon or closed
when to use java streams
java 8 stream

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?

The two calls to s.forEach utilise the same stream hence the exception in the first example whereas the call to the stream() method --> numbers.stream() generates (yields) a new stream each time hence doesnt throw a "java.lang.IllegalStateException: stream has already been operated upon or closed".

A Guide to Streams in Java 8: In-Depth Tutorial With Examples, forEach() is a terminal operation, which means that, after the operation is performed, the stream pipeline is considered consumed, and can no  10 Project build error: 'dependencies.dependency.version' for org.springframework.cloud:spring-cloud-starter-eureka-server:jar is missing Aug 19 '18. 9 Java 8 - Once Stream is consumed and operated giving error, but in another case its not Oct 7 '18.

.stream() creates a new instance of a Stream despite the fact it's called on the same collection

Java 8 Friday: 10 Subtle Mistakes When Using the Streams API , Java 8 Friday Every Friday, we're showing you a couple of nice new Yet Another 10 Common Mistakes Java Developers Make When Writing SQL (it's Friday the 13th), we'll catch up with what will go wrong in YOUR So be careful when consuming your stream. And the list after stream consumption? Intermediate operations are never the final result producing operations. Commonly used intermediate operations are filter and map. Java 8 Stream API operations that returns a result or produce a side effect. Once the terminal method is called on a stream, it consumes the stream and after that we can’t use stream.

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.

Java 8 Friday: 10 Subtle Mistakes When Using the Streams , But we haven't done a top 10 mistakes list with Java 8 yet! Wanna bet, this will happen to everyone at least once. So be careful when consuming your stream. forEach(a), no checks or other computation * occur anywhere other than Error guessing means that the tester designs test cases based on  private static List<Employee> empList = Arrays.asList(arrayOfEmps); empList.stream(); Note that Java 8 added a new stream () method to the Collection interface. And we can create a stream from individual objects using Stream.of (): Stream.of(arrayOfEmps[0], arrayOfEmps[1], arrayOfEmps[2]);

forEach is a terminal operation.

After the terminal operation is performed, the stream pipeline is considered consumed, and can no longer be used;

https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

What's Wrong in Java 8, Part III: Streams and Parallel Streams, Java 8 parallel streams may make your programs run faster. Or not. Thinking about map, filter and other operations as “internal iteration” is a This may surprise you, since you may create an empty list and add elements after. What Java 8 streams give us is the same, but lazily evaluated, which means  One should note that a Stream can never really be an Iterable because it can't be invoked more than once. However, if you are certain that the Stream will only be iterated once, to create an Iterable from a stream, one only need to use the expression myStream::iterator

Java Streams Cheat Sheet, These operation pipelines are tricky, so having a Java Streams cheat sheet can help of functions on a data structure, but a stream itself is not a data structure. in another data structure or perhaps consumed by another operation. The elements themselves before and after the filter will have the same  No storage. A stream is not a data structure that stores elements; instead, it conveys elements from a source such as a data structure, an array, a generator function, or an I/O channel, through a pipeline of computational operations. Functional in nature. An operation on a stream produces a result, but does not modify its source.

Java 8 Stream - Java Stream, We just want to know the sum of integers but we would also have to provide Most of the Java 8 Stream API method arguments are functional interfaces, Since the data is on-demand, it's not possible to reuse the same stream multiple times. Once the terminal method is called on a stream, it consumes the stream and  In Java 8, Stream can hold different data types, for examples: But, the Stream operations (filter, sum, distinct…) and collectors do not support it, so, we need flatMap () to do the following conversion : 1.1 The below example will print an empty result, because filter () has no idea how to filter a stream of String [].

How to print elements of a Stream in Java 8, Introduced in Java 8, the Stream API is used to process collections of objects. There are 3 ways to print the elements of a Stream in Java: Hence the below code will throw an error since the stream is already consumed. This is an intermediate operation i.e, it creates a new stream that, when traversed, contains the  We’re migrating our code base to Java 8. We’ll replace everything by functions. Throw out design patterns. Remove object orientation. Java 8 has been out for over a year now, and the thrill has gone back to day-to-day business. A non-representative study executed by baeldung.com from May 2015 finds that 38% of their readers have adopted Java 8.

Comments
  • Could you please add more details and I did not follow you