In order to keep implementation details from leaking, instead of returning, e.g., a Collection<MyCoolObject>
, one might implement Iterable<MyCoolObject>
, which would then require implementing Iterator<T>
from the Iterable
Interface. Thus however the internal data structure is managed, the access to the elements is via the Iterator
.
With Java 8, one might wish to add Stream<MyCoolObject> stream()
to MyCoolObject
. (See also: recommendation to support stream
in the book Java 8 Lambdas). While adding the method isn't difficult (and I did read the Question about Why Iterable Doesn't Provide Stream), it seems odd that Java did not add an Interface for Streamable<T>
to mirror the Iterable<T>
idea. (Well, a different name perhaps since Streamable
exists for the ever use CORBA stuff).
I think I followed the Answer about why adding Stream
to Iterable
was potentially problematic, but I do not see why a Streaming<T>
interface couldn't have been provided. For example, Collections
could have implemented the Streaming<T>
interface, and it would make it clearer for other objects that one could expect a stream()
method.
Based upon an Answer to the above referenced Question, it is possible to get a Stream
from the Iterable
via
Stream s = StreamSupport.stream(iter.spliterator(), false);
but that seems like a lot of work given that MyObject
could would like to just implement stream()
to allow a user of the object to do
myObject.stream().filter(...).collect(...)
without the intervening conversion from the iterator.
Is there a reason for the lack of an interface for streaming capable objects? Is there a better approach than just implementing stream()
on MyCoolObject and letting someone look through the Javadoc so they know it has a stream()
method?
Or, is quite likely, am I misunderstanding something about the approach for Stream?
(Also, I implement stream()
in CoolObject, but then forget to implement parallelStream()
, which is something that would be alleviated by having the interface).
The stream head provides the interface between the stream and an application program. After a stream has been opened, STREAMS-related system calls enable a user process to insert and delete (push and pop) modules.
concat() Method of Stream Interface in Java API.
All the members (methods and fields) of an interface are public. All the methods in an interface are public and abstract (except static and default). All the fields of an interface are public, static and, final by default.
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.
This should probably augment any future answers.
I don't know why you think that returning an Iterable<MyCoolObject>
rather than a Collection<MyCoolObject>
is better. It might hide details indeed, and will create more problems as-well.
A Collection has a known size
that plays a big role while splitting for parallel processing. This is reported as Spliterator.SIZED | Spliterator.SUBSIZED
. So a Collection.stream
will handle parallel streams much better then a Iterable
, that will use:
public static <T> Spliterator<T> spliteratorUnknownSize
that is documented as:
... and implements trySplit to permit limited parallelism.
Which is obvious, since you don't know the size at all. Under the current implementation the batch size is 1024
. So, for example, for anything under 1024 elements you would not get any parallelisation at all.
Now as far as your question goes, there used to be such a thing in the early builds of jdk-8. It was called java.util.stream.Streamable
. From what I know it was removed because there are methods that return a Stream
, but not via the stream()
method.
String::codePoints()
File::lines
Pattern::splitAsStream
... many others
So the only place where this would be implemented would be the Collections. And that as far as I can tell this would be a really isolated place.
Aha moment
Here is the explanation from the people in charge of this.
As suggested here are the reasons for the removal:
I am considering dropping the Streamable interface. Currently the only implementor is Collection, and all of the other stream-bearing methods are serving up specialized streams (chars(), codePoints(), lines(), etc) with a method name that is more suitable than "stream". So I think we should drop Streamable and leave the stream() / parallel() methods on Collection (or possibly move them up Iterable).
Because it was removed, but you can easily roll out your own Streamable
implementation if you need it:
@FunctionalInterface
interface Streamable<T> {
Stream<T> stream();
}
If we take the example of the strategy pattern, you would then define it like so:
interface StreamStrategy<T> {
Streamable<T> getStreamable();
}
Which can easily be implemented based on any backing object providing a method returning a Stream<T>
, using a method reference. For example, if you have a collection:
class CollectionBasedStrategy<T> implements StreamStrategy<T> {
@Override
public Streamable<T> getStreamable() {
return new ArrayList<T>()::stream;
}
}
If Collection
was extending such a Streamable
interface, you would indeed not need to use the method reference. But otherwise there didn't seem to be much added value to put that in the JDK – and it can still be added later if needed.
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