Wednesday, 4 May 2016

java.lang.IllegalStateException: stream has already been operated upon or closed- FIX

java.lang.IllegalStateException: stream has already been operated upon or closed

In Java 8 a Stream object cannot be reused after it has been reused or worked upon.
After any Stream operation, that particular Stream will be closed automatically.

See the Example below:

import java.util.Arrays;
import java.util.stream.Stream;

public class StreamTestingClass {
 public static void main(String[] args) {

 String[] array = new String[]{"a", "b","c","d"};
        Stream dataStream = Arrays.stream(array);
        
        //Using the dataStream 1st time
        dataStream.forEach(System.out::println);

        //Using the dataStream for the 2nd time.. GIVES EXCEPTION!!
        dataStream.forEach(System.out::println);
 }
}


This will give the following Exception:

a
b
c
d
Exception in thread "main" java.lang.IllegalStateException: stream has already been operated upon or closed
 at java.util.stream.AbstractPipeline.sourceStageSpliterator(AbstractPipeline.java:279)
 at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
 at codermag.net.java8.StreamTestingClass.main(StreamTestingClass.java:15)




This proves that the command executes for the 1st time.
For the 2nd time it fails.


SOLUTION: Use java.util.function.Supplier Class

To reuse a Stream we need to use java.util.function.Supplier.
java.util.function.Supplier allows you to get multiple instance of the same Stream.


import java.util.Arrays;
import java.util.function.Supplier;
import java.util.stream.Stream;

public class StreamTestingClass {
 public static void main(String[] args) {

  String[] array = new String[]{"a", "b","c","d"};
       
  Supplier<Stream<String>> streamSupplier = () -> Arrays.stream(array);
        
  //get a copy of the stream
  streamSupplier.get().forEach(System.out::println);

        //get another copy of the stream
  streamSupplier.get().forEach(System.out::println);
 }
}


The get() operation of java.util.function.Supplier.get() is used to get a new instance of the Stream.
This will help you to work on the Stream multiple times. Just call the get() as many times as required.




No comments:

Post a Comment

Coder Magnet
CoderMagnet is full of resources from our daily development activities. It has solutions for common problematic scenarios in technologies like Java 8, AEM, JCR and also occasionally gives you tips on Blogger as well.