The answer is, as always, “it depends”. It depends on how big the returned collection will be. It depends on whether the result changes over time and on the importance of the consistency of the returned result. And it really depends on how the user is likely to use the answer.
First, keep in mind that you can always get a collection from a stream and vice versa:
// If API returns Collection, convert with stream() getFoo().stream()... // If API returns Stream, use collect() Collection
c = getFooStream().collect(toList());
So the question is which is more useful for your callers.
If your result could be infinite, there is only one choice: Stream.
If your result could be very large, you probably prefer Stream, since there may be no value in materializing it all at once, and that could create significant heap pressure.
If all the caller is going to do is scroll through it (search, filter, aggregate), you should prefer Stream, as Stream already has these built-ins and there is no need to materialize a collection (especially if the user may not be processing the overall result.) This is a very common case.
Even if you know the user will repeat it multiple times or otherwise keep it, you may still want to return a Stream, for the simple fact that whatever collection you choose to include (for example, ArrayList) may not be the module they want. so the caller has to copy it anyway. if a stream is returned, they can execute
collect(toCollection(factory)) and get it exactly in the desired shape.
The aforementioned “prefer Stream” cases arise mainly from the fact that Stream is more flexible; you can tie yourself up late to how you use it without incurring costs and constraints to materialize it in a Collection.
The only time a collection needs to be returned is when there are high consistency requirements and a consistent snapshot of a moving target must be produced. So, you will want to put the elements in a collection that won’t change.
So I’d say most of the time Stream is the right answer – it’s more flexible, doesn’t impose usually unnecessary re-material costs, and can easily be transformed into the Collection of your choice if needed. Sometimes, however, it may be necessary to return a collection (for example, due to high consistency requirements) or you can return the collection because you know how the user will use it and know that this is the most convenient thing for them. .