This question already has an answer here:
-
Should I return a Collection or a Stream?
8 answers
In Java 8 I am increasingly replacing Collection
return values with Stream
.
So where I would once have had:
public List<Element> getElementList() {
return elements;
}
I am now using:
public Stream<Element> streamElements() {
return elements.stream();
}
My arguments for this are:
- It enforces the immutability of the underlying list
- It hides the fact that there is an underlying list. It could later be changed to a set or some other structure without changing the method signature.
- It nicely encapsulates that the user of the method is expected to do something with the items not something with a list.
- It can be trivially parallelised later if required.
In fact now, in my code, returning a List
or some other collection is explicitly a recognition that the user may consider the collection mutable and is expected to be able to change it.
Clearly some of this can be achieved with immutable collections.
My question is: can anyone see any disadvantages with this design? Are there any advantages of immutable collections over returning a Stream
?
I'm not saying you shouldn't return a Stream, and even less that you should never return a Stream, but doing it also has many disadvantages:
- it doesn't tell the user of the API if the collection is ordered (List) or not (Set), or sorted (SortedSet)
- it doesn't tell the user of the API if the collection can contain duplicates (List) or not (Set)
- it doesn't allow the user to easily and quickly access the first or last element of the list, or even to know which size it has.
- if the user of the API needs to do multiple passes over the collection, he's forced to copy every element into a new collection.
I would say that choosing to return a stream rather than a collection also depends on what you already have. If the collection is already materialized (think about a JPA entity having a OneToMany already materialized as a Set), I'd probably return an immutable wrapper over the collection. If, on the other hand, the collection to return is the result of a computation or transformation of another collection, returning a Stream might be a better choice.
I can think of several cases:
- When the caller really wants to "get and hold" the values instead of processing them just once.
- When returning each time a new object is not acceptable for memory or performance issue, where returning a static object is preferable (this is possible for high performance computing or where you want to have deterministic processing time in the method so you want to have minumal GC).
But yes a lot of processing can be simplified.