Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Stream StreamSupplier

I'm using following code to reuse Stream but getting

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

Code

public static void main(String[] args) {

    try {
        String[] array = { "a", "b", "c", "d", "e" };
        Stream<String> ss = Stream.of(array);
        Supplier<Stream<String>> streamSupplier = () -> ss;

        long count = streamSupplier.get().count();
        // get new stream
        streamSupplier.get().forEach(x -> System.out.println(x));

        // get another new stream

        System.out.println(count);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
like image 304
Nishant Kumar Avatar asked Jul 18 '18 13:07

Nishant Kumar


People also ask

Can you use a stream on an array?

The stream(T[] array) method of Arrays class in Java, is used to get a Sequential Stream from the array passed as the parameter with its elements. It returns a sequential Stream with the elements of the array, passed as parameter, as its source.

What is stream () in Java?

A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. The features of Java stream are – A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.

How do I use two streams in Java 8?

concat() in Java. Stream. concat() method creates a concatenated stream in which the elements are all the elements of the first stream followed by all the elements of the second stream. The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel.

How to use streambuilder to generate numbers per second?

To use StreamBuilder, you need to call the constructor below. Basically, you need to create a Stream and pass it as the stream argument. Then, you have to pass an AsyncWidgetBuilder which can be used to build the widget based on the snapshots of the Stream. Below is a simple function that returns a Stream for generating numbers every one second.

How to add a stream<string> to a supplier?

You create the Stream<String> before you put it to the Supplier. If you want the Supplier to provide a new Stream witch each call, create the Stream<String> directly in the Supplier. Then streamSupplier.get () will always work with the new Stream<Stream>.

What are streams and how to use them?

Streams are normally used when reading data from large files. By using streams, the data from large files in broken down into small chunks and sent to the stream. These chunks of data can then be read from the application. The reason for breaking it down into small chunks is because of the performance impact of reading a big file in one shot.

How do I use streambuilder in flutter?

In Dart, you can create a function that returns a Stream, which can emit some values while the asynchronous process is active. If you want to build a widget in Flutter based on the snapshots of a Stream, there's a widget called StreamBuilder. This tutorial explains how to use the widget. To use StreamBuilder, you need to call the constructor below.


2 Answers

Stream::count is the terminal operation which closes the Stream, so no more pipelines can proceed.

You create the Stream<String> before you put it to the Supplier. If you want the Supplier to provide a new Stream witch each call, create the Stream<String> directly in the Supplier.

Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);

Then streamSupplier.get() will always work with the new Stream<Stream>.


Yet, you might achieve the same result with Stream::peek which works the same like Stream::forEach with an exception that it doesn't close the Stream but returns the same unmodified one (@Lino was faster).

long count = streamSupplier.get().peek(System.out::println).count();
like image 39
Nikolas Charalambidis Avatar answered Sep 26 '22 04:09

Nikolas Charalambidis


Don't assign Stream.of(array) to an intermediate variable, just return it directly in the Supplier:

Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);

That is because previously you would just always supply the same reference when calling supplier.get() but in fact you wanted to return a new Stream.

Also as @Eugene suggested, using Arrays.stream() over Stream.of() is preferred. As the latter is a varargs method, but just delegates to the former.


Also your current approach can be simplified using the Stream.peek() method:

long count = Arrays.stream(array)
    .peek(System.out::println)
    .count();
like image 79
Lino Avatar answered Sep 22 '22 04:09

Lino