How to implement a Java stream?
I want to implement a Stream<T>
.
I don't want to just use implements Stream<T>
, because I would have to implement a ton of methods.
Can this be avoided?
To be more concrete, how can I stream t1
, t2
and t3
for example:
class Foo<T> {
T t1, t2, t3;
Foo(T t1, T t2, T t3) {
this.t1 = t1;
this.t2 = t2;
this.t3 = t3;
}
}
Solution 1:
The JDK's standard implementation of Stream
is the internal class java.util.stream.ReferencePipeline
, you cannot instantiate it directly.
Instead you can use java.util.stream.Stream.builder()
, java.util.stream.StreamSupport.stream(Spliterator<T>, boolean)
and various1, 2 other static factory methods to create an instance of the default implementation.
Using a spliterator is probably the most powerful approach as it allows you to provide objects lazily while also enabling efficient parallelization if your source can be divided into multiple chunks.
Additionally you can also convert streams back into spliterators, wrap them in a custom spliterator and then convert them back into a stream if you need to implement your own stateful intermediate operations - e.g. due to shortcomings in the standard APIs - since most available intermediate ops are not allowed to be stateful.
See this SO answer for an example.
In principle you could write your own implementation of the stream interface, but that would be quite tedious.
Solution 2:
If you're wanting to make your own Stream because you want custom close()
logic, the simplest solution is to create a Stream from an Iterator, and call onClose(Runnable)
. For instance, to stream from a Reader via Jackson:
MappingIterator<?> values = objectMapper.reader(type).readValues(reader);
return StreamSupport
.stream(Spliterators.spliteratorUnknownSize(values, Spliterator.ORDERED), false)
.onClose(() -> {
try {
reader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
});