Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call multiple terminal operation on a Java stream

I know that whenever we call any terminal method on a stream, it gets closed.

If we try to call any other terminal function on a closed stream it will result in a java.lang.IllegalStateException: stream has already been operated upon or closed.

However, what if we want to reuse the same stream more than once?

How to accomplish this?

like image 418
Mehraj Malik Avatar asked Mar 02 '17 10:03

Mehraj Malik


People also ask

Can stream pipeline have multiple terminal operations?

Chaining A stream can execute any number of intermediate operations, which is termed stream chaining. A stream can have only one terminal operation, it cannot be chained.

What happens when one calls two terminal operations on a stream?

I know that whenever we call any terminal method on a stream , it gets closed. If we try to call any other terminal function on a closed stream it will result in a java. lang. IllegalStateException: stream has already been operated upon or closed .

How many terminal operations can you perform use on any given stream?

Pipeline of operations can have maximum one terminal operation, that too at the end. Intermediate operations are lazily loaded.

Which methods are terminal operations applied on streams?

Finding an Element in a Stream. The Stream API gives you two terminal operations to find an element: findFirst() and findAny() . These two methods do not take any argument and return a single element of your stream.


1 Answers

Yes its a big NO in Java 8 streams to reuse a stream

For example for any terminal operation the stream closes when the operation is closed. But when we use the Stream in a chain, we could avoid this exception:

Normal terminal operation:

Stream<String> stream =
    Stream.of("d2", "a2", "b1", "b3", "c")
        .filter(s -> s.startsWith("a"));

stream.anyMatch(s -> true);    // ok
stream.noneMatch(s -> true);   // exception

But instead of this, if we use:

Supplier<Stream<String>> streamSupplier =
    () -> Stream.of("d2", "a2", "b1", "b3", "c")
            .filter(s -> s.startsWith("a"));

streamSupplier.get().anyMatch(s -> true);   // ok
streamSupplier.get().noneMatch(s -> true);  // ok

Here the .get() "constructs" a new stream and NOT reuse whenever it hits this point.

Cheers!

like image 58
Vijayan Kani Avatar answered Oct 14 '22 03:10

Vijayan Kani