List<Person> persons = Humans.list(); List<Person> adults = new ArrayList<Person>(); for(Person p: persons) { if(p.age>=18){ adults.add(p); } }
Notice how the logic (filtering a list) gets drowned in irrelevant details such as creating the result list, iterating over the list, and accumulating the matching elements.
The alternative (the poor man's functional Java) with libs like Google collections would look like:
List<Person> adults = persons.filter(new Filter<Person>() {
@Override public boolean accept(Person t) { return t.age>=18; } });
Notice the noise added by the anonymous inner class.
Now, with lambdas, we end up with (once the collections are augmented methods like filter, map, reduce, etc.):
List<Person> adults = persons.filter(#{p -> p.age >= 18});
A one-liner, where the core logic (comparing the age to 18) clearly stands out.
The auto conversions of lambdas to SAM types is a spark of genius if you ask me. But I'm not happy with the decision of not implementing structural types in Java. IMO, this will lead to a Cambrian explosion in the number of SAM types, types like Mapper<S, T>, Reducer, Folder, Filter or Predicate, plus the custom types added by various frameworks.