We read:
final Optional<String> aLongName =
friends.stream()
.reduce((name1, name2) ->
name1.length() >= name2.length() ? name1 : name2);
aLongName.ifPresent(name ->
System.out.println(String.format("A longest name: %s", name)));
I suggest to use the variable names “running” and “current” to make clear how the lambda is called (this also applies to the code on the next page involving steve
).
I wanted to use “accumulator” instead of “running” but the JavaDoc for reduce
calls the whole of the lambda “accumulator”: public abstract java.util.Optional<T> reduce(java.util.function.BinaryOperator<T> accumulator)
final Optional<String> aLongName =
friends.stream()
.reduce((running, current) ->
running.length() >= current.length() ? running : current);
aLongName.ifPresent(name ->
System.out.println(String.format("A longest name: %s", name)));
and
final String steveOrLonger =
friends.stream()
.reduce("Steve", (running, current) ->
running.length() >= current.length() ? running : current);
P.S.
One may note that reduce()
correctly works for lists of length 0 or 1 without surprises!
… as can be ascertained by this side-effecting modified stream sequence (the original prints nothing on an empty list).
final Optional<String> aLongName =
friends.stream()
.reduce((running, current) -> {
System.out.println(String.format("(%s,%s)",running,current));
return (running.length() >= current.length() ? running : current);
} );
String result = (aLongName.isPresent() ? String.format("A longest name: %s", aLongName.get()) : "No name in list");
System.out.println(result);
But the above is explained the next page
The result of the
reduce()
method is anOptional
because the list on whichreduce()
is called may be empty. In that case, there would be no longest name. If the list had only one element, thenreduce()
would return that element and the lambda expression we pass would not be invoked.
P.P.S.
One may note that this is an instance of the fold-left
pattern of functional programming:
…But how would one compute the average of the name lengths? Or perform a fold-right
where we need to know the last element first? (Keep reading I guess)