Skip to content
Advertisement

Java 8 reduce method calls depending on a value

How to optimize method that returns the first non empty value returned of the checkN() methods and prevent the rest method calls and isEmpty() calls:

private String validate() {
    String message = check1();

    if (message.isEmpty()) {
        message = check2();
    }

    if (message.isEmpty()) {
        message = check3();
    }

    // total 5+ checks been called

    return message;
}

#1 I thought of using stream filter and return first that has value, but it requires to call each check:

return Stream.of(check1(), check2(), check3(), ...).filter(message -> !message.isEmpty()).findFirst().orElse("");

SOLVED

as M A suggested, finalized solution for me was:

public static String method(Some a, Other b) {
        return Stream.<Supplier<String>>of(
                // for the methods without params
                myClass::check1,
                // for the methods with params
                () -> check2(a),
                () -> check3(a, b))
        .map(Supplier::get)
        .filter(StringUtils::isNotBlank)
        .findFirst().orElse("");
}

Advertisement

Answer

Instead of constructing a Stream of Strings, you can do a Stream of Supplier<String>, which would defer the invocation of the method until the filter needs to be checked in the stream pipeline:

return Stream.<Supplier<String>>of(this::check1, this::check2, this::check3, ...)
            .filter(check -> !check.get().isEmpty())
            .findFirst()
            .map(Supplier::get)
            .orElse("");

A better variant is to do the mapping from Supplier to the result String before the filter (the advantage is that this won’t call the method with the non-empty result twice):

return Stream.<Supplier<String>>of(this::check1, this::check2, this::check3, ...)
            .map(Supplier::get)
            .filter(message -> !message.isEmpty())
            .findFirst()
            .orElse("");
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement