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();
}
}
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.
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.
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.
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.
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>.
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.
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.
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();
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();
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