- For most of the cases you should return
Stream. It is more flexible, is designed for better performance, and can be easily turned into
- You should return
Collectionwhen there are strong consistency requirements and you have to produce snapshot of a moving target. Then you will want to put the elements into a collection that will not change.
Recently at my work, we were talking about our old legacy code. We talked about first projects using Java 8 and Streams API.
We came to the conclusion that it has an enormous amount of that API in it. Methods return streams everywhere, and even streams of streams.
I started wondering what is the correct - also known as best practice - of returning a collection in Java, having in mind Java 8 new stream API. I found that for the most of the cases I return simple
Collection, or even an
Iterable. Very seldom, when I want to ensure caller what is the type of data he receives I also return
But the question that I had in mind was: what is the idiomatic way of returning a collection of objects when a caller should not care about its internals and ordering / duplicate invariants. Making a long story short: is
Stream a new and right way of returning more than 1 item?
Luckily the answer was posted by Brian Goetz - co-author of Java Stream API.
He stated that for most of the cases the
Stream is the preferable type to be returned for a collection of elements.
Of course, like everything it depends, but generally speaking, it should be your first choice. Why? There are a couple of reasons.
It can give you an infinite number of items. If the result might be very large producing items one by one - instead of materializing them all into one collection - is better for your heap. When a caller is filtering, aggregating & limiting the number of items,
Stream already has built-in methods to do that. It’s lazy loaded. Items are given only when you actually use them, instead of a moment when you declare stream.
One thing that you have to consider using streams is that reading from them is a
terminal operation. It means you can’t read the same stream twice.
That may be a problem when you want to call multiple methods on a stream, like below.
Stream<Long> lottoNumbers = lotto.numbers();
In such scenarios, you can go one of two ways. First is to return a
Collection. Second to collect received stream with
Stream.collect(Collectors.toList()) for example.
So as creators said I encourage you to return
Stream as your first and preferable choice and return other collection after a thought that will tell you it’s a better in a given scenario.
And please. Do not return stream of streams ;)