FlorianF FlorianF - 1 year ago 60
Java Question

Decision between using a Stream or a Loop

By writing applications in Java there are many use cases for

was introduced with Java 8, I came over some use-cases where it is difficult to decide what to use.

For example:
You are going to write some util-methods.

public static List<?> filterHashToList(int hash, Collection<?> toFilter) {
return toFilter.stream()
.filter((Object o) -> hash == o.hashCode())

What about writing it like this:

public static List<?> filterHashToList(int hash, Collection<?> toFilter) {
List<Object> result = new LinkedList<>();

for(Object o : toFilter) {
if(hash == o.hashCode()) {

return result;

Both methods would produce the same result.
are interfaces, so the implementation can vary as well if I use custom streams and collectors.

I think there are loads of implementations out there using the old-fashoined loop-way.

So, is it possible to answer what to use, stream or loop, by use-case?
And if so, do all implementations have to be updated where appropriate?

Or should I even provide both ways by implementing util-methods?
Or should I also provide a mthed returning the stream after the filtering process so you can work with that one too if required?

Answer Source

Note that in your implementation you stick with specific resulting collection type LinkedList which usually has very poor performance compared to ArrayList. What if the user of your method wants to use the resulting list in random-access manner? Probably the user of this method needs an array, because it should be passed to another API method which accepts an array. Sometimes the user just need to know how many objects with given hashCode are present in the input collection, thus there's no need to create a resulting list at all. The Java-8 way is to return streams from the methods, not the collections and let the caller decide how to collect it:

public static <T> Stream<T> filterHashToList(int hash, Collection<T> toFilter) {
    return toFilter.stream()
        .filter(o -> hash == o.hashCode());

And use it:

filterHashToList(42, input).count();


filterHashToList(42, input).collect(toCollection(ArrayList::new));


filterHashToList(42, input).toArray();

This way the method becomes very simple, so you probably don't need it at all, but if you want to do more sofisticated filtering/transformation, it's ok.

So if you don't want to change the API and still return the LinkedList, there's no need to change the implementation. But if you want to take the advantage from using Stream API, it's better to change the return type to Stream.