Functional Programming in Java, Second Edition: p.39 PickALongest.java

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 an Optional because the list on which reduce() is called may be empty. In that case, there would be no longest name. If the list had only one element, then reduce() 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)