【问题标题】:Using Java Predicate and Lambda使用 Java 谓词和 Lambda
【发布时间】:2018-12-05 13:08:45
【问题描述】:

为什么下面的代码返回Predicate<String> 而不是boolean

我的理解是,这里的!s.isEmpty()检查与谓词boolean test(T t);背道而驰,这里的返回类型是boolean

所以在我的 lambda 中,我的 nonEmptyStringPredicate 不应该是 boolean 类型吗?显然,不是,我只是想了解为什么不是。

Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();

【问题讨论】:

  • 您似乎混淆了 lambdas 执行/返回 的功能,以及它 实现 的功能接口类型(作为它可以是什么类型的实例使用)。

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


【解决方案1】:

在这种情况下,Predicate 获取 String 作为参数并返回 boolean。 如果我们不把它写成 lambda,它看起来像这样:

Predicate<String> somePredicate = new Predicate<String>() {
    @Override
    public boolean test(String string) {
        return !string.isEmpty();
    }
};

【讨论】:

  • 谢谢! - 因此,如果我要使用 Predicate,它将始终返回我传入的 Predicate,在本例中为 String.
  • 不客气。如果您需要有关 lambda 的更多信息,请查看 this。顺便说一句,您不应该忘记接受答案以向其他人展示问题已解决。
【解决方案2】:

如果你真的愿意从Predicate 得到一个布尔值,你可以使用它的test 方法:

Predicate<String> nonEmptyStringPredicate = s -> !s.isEmpty();
boolean val = nonEmptyStringPredicate.test("any"); // true

另一方面,Predicate 只是一个 FunctionalInterface,您使用 lambda 表达式表示。

【讨论】:

    【解决方案3】:

    Lambda 就像一个匿名类,所以:

    Predicate<String> nonEmptyStringPredicate = (String s) -> !s.isEmpty();
    

    就像:

    Predicate<String> nonEmptyStringPredicate = new Predicate<String>() {
        public boolean test(String s) {
            return !s.isEmpty();
        }
    }
    

    【讨论】:

    • Lambda 和 AIC 相似,但又不相同。它们有一些细微差别(即this 的含义),并且它们的实现方式完全不同。
    • 你是对的,但我确实认为这是一种可视化 lambdas 或向人们解释他应该如何使用它们的好方法。
    【解决方案4】:

    为什么下面的代码返回 Predicate 而不是布尔值?

    这是因为 函数 (String s) -&gt; !s.isEmpty() 的类型是 Predicate&lt;String&gt;,此时您只是在定义 一个函数(它表示“给定一个字符串作为输入返回一个布尔值指示它是否为空)。

    请注意,此时您没有评估任何内容,因此结果不是布尔值,而是函数

    文档中FI的定义:

    函数式接口为 lambda 表达式和 方法参考。每个功能接口都有一个抽象 方法,称为该功能接口的功能方法,以 lambda 表达式的参数和返回类型匹配 或改编。函数式接口可以提供一个目标类型 多个上下文,例如赋值上下文、方法调用或 投射上下文:

    为了获得您正在寻找的“布尔结果”,您必须首先调用“功能方法”。示例:

    Predicate<String> nonEmptyStringPredicate = s -> !s.isEmpty();
    boolean result = nonEmptyStringPredicate.test(""); 
    

    【讨论】:

      【解决方案5】:

      谓词总是返回一个布尔值,所以这里唯一有趣的值是输入参数,它是一个字符串。

      见:https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html

      【讨论】:

        【解决方案6】:

        它返回一个谓词,因为在左侧您将谓词声明为返回类型,而在右侧您将返回 Predicate 的 test() 方法的实现。 当您的代码返回一个作为功能接口实现的对象时(如您的情况),您只需返回其单个抽象方法的逻辑,在本例中为test() 所以基本上就像你要返回这个: Predicate&lt;String&gt; nonEmptyStringPredicate = new Predicate { @Override boolean test(String input) { return input.isEmpty() } } 当您编写代码时,编译器“知道”!s.isEmpty() 是方法 test 的逻辑,它基本上告诉您“嘿,只给我逻辑,我不需要样板代码” 顺便说一句,使用方法参考是一种很好的做法,您可以将!s.isEmpty() 替换为!String::isEmpty

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多