First you need to know how forEach
is defined:
void forEach(Consumer<? super T> action)
The documentation states that the default implementation behaves like:
for (T t : this)
action.accept(t);
A Consumer<T>
is a functional interface that:
Represents an operation that accepts a single input argument and returns no result.
.
The specified action can be called using lambda syntax. If there is a class like this:
class Person
{
String Name
int Age
}
and an action that uses this class Consumer<Person>
, then it can be used/called like this:
p -> p.Name
The first variant using the lambda syntax is applying the specified method (in this case System.out.println
) to the parameter name
. You can read the line as:
for each name from the list names do System.out.println(name)
The second variant is using the nature of the Consumer inerface in order to apply the function to every item of the list without the need to specify the parameter explicitly, because this is done automatically (because of the matching signature) and it is called Method Reference.
So this allows a call to a method expecting only one Consumer<T>
argument:
This is a functional interface whose functional method is accept(Object).
.
And in this case the forEach
construct happens to be one such method and that is why the parameter name
could be omitted from the call, thus leading to the syntax:
list.forEach(someMethodWithOneParameterOnly);
In background the call is transformed again to:
for each item from list do someMethodWithOneParameterOnly(item)