对 Lambda 对象 returns 值的方法调用

Method call on a Lambda object returns value

lambda 表达式 j8Test.PerformChange$$Lambda/284720968@2f4d3709

上的表达式 this.apply(stringValue) returns true

为什么 return 是真的而不是假的。为什么它 return 实际上什么都没有? (我不是在谈论 PerformChangeImpl 类型的所有其他对象)

private final List<PerformChange> performChangeList = Arrays.asList(
        new PerformChangeImpl("1"),
        new PerformChangeImpl("2"),
        new PerformChangeImpl("3")
);

@FunctionalInterface
interface PerformChange extends Function<String, Boolean> {

    default PerformChange performChange(PerformChange input) {
        System.out.println("1 this: " + this);
        System.out.println("2 input: " + input);
        return stringValue -> {
            System.out.println("\n3 this: " + this);
            System.out.println("4 input: " + input);
            if (this.apply(stringValue)) {
                System.out.println("5 this: " + this);
                return input.apply(stringValue);
            }
            return false;
        };
    }
}

class PerformChangeImpl implements PerformChange {

    private final String value;

    public PerformChangeImpl(String value) {
        this.value = value;
    }

    @Override
    public Boolean apply(String string) {
        System.out.println("\n6: " + this);
        System.out.println("7: " + string);
        return true;
    }

    @Override
    public String toString() {
        return "obj id: " + value;
    }
}

private void executePerformChanges() {
    System.out.println(performChangeList.stream()
            .reduce(PerformChange::performChange)
            .orElse(new PerformChangeImpl("4"))
            .apply("test"));
}

结果

1 this: obj id: 1
2 input: obj id: 2
1 this: j8Test.PerformChange$$Lambda/284720968@2f4d3709
2 input: obj id: 3

3 this: j8Test.PerformChange$$Lambda/284720968@2f4d3709
4 input: obj id: 3

3 this: obj id: 1
4 input: obj id: 2

6: obj id: 1
7: test
5 this: obj id: 1

6: obj id: 2
7: test
5 this: j8Test.PerformChange$$Lambda/284720968@2f4d3709

6: obj id: 3
7: test
true

Process finished with exit code 0

这里:

public Boolean apply(String string) {
  ...

您的 class PerformChangeImpl 覆盖了 apply() 方法。那是 Function 接口的核心。

最后,您的代码调用:

.apply("test"))

apply() 中的最后一句话是:

return true;

方法 returns true,因为你告诉它这样做。因此,您应该根据某些条件将该方法主体更改为 return true / false,或者您最终不应该调用 apply()

注意:这从打印语句中变得非常明显。最后,你得到 67,你在 PerformChangeImpl class 的 apply() 中打印它们。

另请注意:您的默认方法会:

if(this.apply(stringValue)) { 

在 "surrounding" PerformChangeImpl 上调用 apply() ... 并将 return true

您有两个 PerformChange 的实现:

  1. class PerformChangeImpl functional method apply 总是 returns true。没有机会获得false.
  2. 您在 performChange 中生成的 lambda 表达式 str -> apply(str) && input.apply(str)(我稍微简化了它)。如果 apply(str)input.apply(str) returns false.
  3. 有机会获得 false

由于 performChangeList 只包含 PerformChangeImpl 个实例,生成的 lambda 可以简化为 input.apply(str),换句话说,该方法看起来像

default PerformChange performChange(PerformChange input) {
    // str -> apply(str) && input.apply(str)
    // str -> true && input.apply(str)
    // str -> input.apply(str)
    // input::apply
    // input
    return input;
}

并且只要 performChangeList 完全由 PerformChangeImpl 个对象填充,任何给定的 String 都应该得到 true

附带说明一下,Function<String, Boolean> 就是 Predicate<String>,最好使用后者。

@FunctionalInterface
interface PerformChange extends Predicate<String> { ... }

class PerformChangeImpl implements PerformChange {
    @Override
    public boolean test(String string) { ... }
}