Java 8 - Best way to transform a list: map or foreach?

Emilien Brigand picture Emilien Brigand · Feb 4, 2015 · Viewed 163.3k times · Source

I have a list myListToParse where I want to filter the elements and apply a method on each element, and add the result in another list myFinalList.

With Java 8 I noticed that I can do it in 2 different ways. I would like to know the more efficient way between them and understand why one way is better than the other one.

I'm open for any suggestion about a third way.

Method 1:

myFinalList = new ArrayList<>();
myListToParse.stream()
        .filter(elt -> elt != null)
        .forEach(elt -> myFinalList.add(doSomething(elt)));

Method 2:

myFinalList = myListToParse.stream()
        .filter(elt -> elt != null)
        .map(elt -> doSomething(elt))
        .collect(Collectors.toList()); 

Answer

herman picture herman · Feb 4, 2015

Don't worry about any performance differences, they're going to be minimal in this case normally.

Method 2 is preferable because

  1. it doesn't require mutating a collection that exists outside the lambda expression,

  2. it's more readable because the different steps that are performed in the collection pipeline are written sequentially: first a filter operation, then a map operation, then collecting the result (for more info on the benefits of collection pipelines, see Martin Fowler's excellent article),

  3. you can easily change the way values are collected by replacing the Collector that is used. In some cases you may need to write your own Collector, but then the benefit is that you can easily reuse that.