Java 8 根据值减少方法调用

Java 8 reduce method calls depending on a value

如何优化 return 是 checkN() 方法的第一个非空值 returned 的方法并防止其余方法调用和 isEmpty() 调用:

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

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

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

    // total 5+ checks been called

    return message;
}

#1 我想到了使用流过滤器和 return 首先是有价值的,但它需要调用每个检查:

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

已解决

按照 M A 的建议,我的最终解决方案是:

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("");
}

您可以构建一个 Supplier<String> 流,而不是构建一个字符串流,这将推迟方法的调用,直到需要在流管道中检查过滤器:

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

更好的变体是在过滤器之前从 Supplier 到结果 String 的映射(优点是这不会调用具有 non-empty 结果的方法两次):

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

您说您首先想到了流过滤器,但在这种情况下并不真正需要流。

  • 创建供应商列表显然是正确的方法
  • 但如果为真(即消息不为空),则需要反转测试条件和return。
  • 继续调用方法,直到测试成功并return发送消息。
List<Supplier<String>> checkList = List.of(this::check1,
        this::check2, this::check3, this::check4, this::check5);

    
private String validate() {
    String message;
    for (Supplier<String> nextCheck : checkList) {
        if (!(message = nextCheck.get()).isEmpty()) {
            return message;
        }
    }
    return "";
}

请注意,您可以使用初始方法但更改条件来实现相同的优化。

public String validiate() {
    String message;
    if (!(message = check1()).isEmpty()) {
        return message;
    }
    if (!(message = check2()).isEmpty()) {
        return message;
    }
    if (!(message = check3()).isEmpty()) {
        return message;
    }
    
    // other message checks
    
    return "";
}