2

What is the reduce method actually doing here? I've read the Oracle docs but I still don't understand what the reduce method is doing here in this example

public static Coder findCoderWithWorstBMI(List<Coder> coders) {
    return coders.stream().sorted(Comparator.comparing(BMICalculator::calculateBMI))
            .reduce((first, second) -> second).orElse(null);
}

private static double calculateBMI(Coder coder) {
    double height = coder.getHeight();
    double weight = coder.getWeight();
    if (height == 0.0)
        throw new ArithmeticException();
    double bmi = weight / (height * height);
    return Math.round(bmi * 100) / 100.0;
}
2
  • 1
    Just as you may know, you can reverse a Comparator as well and then findFirst of such an element. Which then forms a combination of sort+findFirst easily replaceable with min or max APIs. Commented Mar 27, 2020 at 9:54
  • @Naman still it's better not to sort the entire collection Commented Mar 27, 2020 at 10:56

2 Answers 2

5

Take a look at the documentation:

Optional reduce​(BinaryOperator accumulator)

Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.

This means reduce takes a BinaryOperator<T> - a specific function that takes two parameters of type T and produces one with the same type.

You stream might have any number of Coder instances, the reducing function takes two Coders and returns the second one. This means, that from the whole stream the last Coder wrapped in Optional is returned if there are any and empty Optional if the stream was empty in the first place.

Note, that this can be written more efficiently:

coders.stream()
    .max(Comparator.comparing(BMICalculator::calculateBMI))
    .orElse(null);
Sign up to request clarification or add additional context in comments.

2 Comments

@user85421 efficient in terms of performance and readability, that's what I had in mind :)
the only case with such stream to return the value of orElse is when the underlying collection is empty, showing the absence of items and that corresponds logically better to Optional<Coder> rather than coder==null to be returned from the method.
0
.reduce((first, second) -> second).orElse(null);

the reduce method will execute if first and second values are present other orElse(null) which takes a null will return null.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.