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.
The closures that are proposed are more like a bolted on psuedo solution, basically syntactic sugar that makes the language more complex. You can only use them in SAM (Single Abstract Method) situations. If only they just added a simple lisp like lambda expression...
[0] http://cr.openjdk.java.net/~briangoetz/lambda/lambda-state-3...