【问题标题】:Method call on a Lambda object returns value对 Lambda 对象的方法调用返回值
【发布时间】:2019-09-23 10:19:05
【问题描述】:

表达式 this.apply(stringValue) 在 lambda 表达式 j8Test.PerformChange$$Lambda$2/284720968@2f4d3709 上返回 true

为什么它返回真而不是假。为什么它实际上根本没有返回任何东西? (我不是在谈论 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$2/284720968@2f4d3709
2 input: obj id: 3

3 this: j8Test.PerformChange$$Lambda$2/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$2/284720968@2f4d3709

6: obj id: 3
7: test
true

Process finished with exit code 0

【问题讨论】:

标签: java lambda java-8 predicate functional-interface


【解决方案1】:

这里:

public Boolean apply(String string) {
  ...

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

最后,您的代码调用:

.apply("test"))

apply() 中的最后一条语句是:

return true;

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

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

另请注意:您的 defaulted 方法可以:

if(this.apply(stringValue)) { 

在“周围”PerformChangeImpl 上调用apply() ...并将返回true

【讨论】:

  • 如果你有时间在这一行检查断点。我的问题只涉及一次迭代,其中至少有一个 .apply 调用 Lambda 表达式,而不是类型 PerformChangeImpl 的对象,并且返回 true。
  • @AnnaKlein performChangeList 包含三个 PerformChangeImpl 实例,您可以在上面进行流式传输。您在这些对象上调用 apply()。最后,你一直在调用那些对象。
【解决方案2】:

你有两个PerformChange 的实现:

  1. functional method apply 总是返回 true 的类 PerformChangeImpl。没有机会得到false
  2. 您在performChange 中生成的lambda 表达式str -&gt; apply(str) &amp;&amp; input.apply(str)(我稍微简化了一点)。如果apply(str)input.apply(str) 返回false,则有机会获得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&lt;String, Boolean&gt; 就是 Predicate&lt;String&gt;,最好使用后者。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 2012-12-10
    • 1970-01-01
    • 2023-01-03
    相关资源
    最近更新 更多