代码之家  ›  专栏  ›  技术社区  ›  NullPointer

在Java8中,谓词和函数接口有什么区别?

  •  25
  • NullPointer  · 技术社区  · 6 年前

    我知道这可能是一个非常基本的问题,但是我想知道 Predicate 和A Function Java8中的接口?

    Predicate<String> predicateTest  = (s)-> s.length() > 5;       
    System.out.println(predicateTest.test("Predicate"));
    
    Function<String, Boolean> functionTest = str -> str.length()> 5;      
    System.out.println(functionTest.apply("Function"));
    

    在我的例子中,两者都在返回 true 唯一的问题是通话方式不同?

    6 回复  |  直到 6 年前
        1
  •  32
  •   Ousmane D.    6 年前

    两者之间的差异 Predicate<T> Function<T, R>

    首先是A 谓词<t> 严格地 布尔值函数:

             _ _ _ _ _ _ _ 
            |             |
      T --> |  predicate  | --> boolean
            |_ _ _ _ _ _ _|   
    

    然而,对于 功能<T,R> :

             _ _ _ _ _ _ _ 
            |             |
      T --> |   function  | --> R
            |_ _ _ _ _ _ _| 
    

    后者使用任何类型的对象,就像 谓词<t> 启用但可以 变化 在返回类型中。

    的用例 谓词<t> 功能<T,R>

    的用例 谓词<t> 当需要使用一个类型的参数的函数时 T 并返回一个布尔值。例如,在您希望过滤元素流的情况下,从满足条件的流中查找第一个元素,例如 .filter(predicate).findFirst() 或检查流中元素的存在,该元素满足某些条件,例如 anyMatch , noneMatch , allMatch 等。

    的用例 功能<T,R> 当需要使用一个类型的参数的函数时 T 并将其转换为类型 R 例如,打电话的时候 stream.map(func) .

    代码段的解释:

    关于文章中的示例片段 Predicate<String> Function<String, Boolean> 在它们所代表的方面是相同的,即它们都代表一个函数 String 然后返回 boolean . 但是,前者避免装箱返回的值 布尔值 Boolean 而后者则不然。

    也就是说,这并不一定意味着你可以在任何地方使用 谓词<字符串> 您也可以使用 函数<string,布尔值> 反之亦然。

    例子:

    当它编译时:

    Predicate<String> predicate = p -> p.length() == 21;
    Stream<String> stream = stringList().stream().filter(predicate);
    

    这不会:

    Function<String, Boolean> function = p -> p.length() == 21;
    Stream<String> stream = stringList().stream().filter(function);
    

    反之亦然:

    在这种情况下:

    Function<String, Boolean> function = p -> p.length() == 21;
    Stream<Boolean> stream = stringList().stream().map(function);
    

    这不会:

    Predicate<String> predicate = p -> p.length() == 21;
    Stream<Boolean> stream = stringList().stream().map(predicate);
    
        2
  •  6
  •   Eugene    6 年前

    在这种情况下没有区别,它只关系到你可以应用的东西。比如说 allMatch 期望 Predicate 你不能通过 Function 即使逻辑上他们也做同样的事情。

        3
  •  5
  •   Jens Bannmann skiwi    6 年前

    奥敏的回答涵盖了基本的差异。我想补充一点,这两个接口还具有不同的专用默认方法,即可以调用任何实现类的方法:

    • Predicate<T>
      • Predicate<T> and(Predicate<? super T> other) -返回表示此谓词和另一个谓词的短路逻辑与的复合谓词。
      • Predicate<T> or(Predicate<? super T> other) -返回表示此谓词和另一个谓词的短路逻辑或的复合谓词。
      • negate() -返回表示此谓词逻辑否定的谓词。
    • Function<T,R>
      • <V> Function<T,V> andThen(Function<? super R,? extends V> after) -返回一个组合函数,该函数首先将此函数应用于其输入,然后应用 after 对结果的函数。
      • <V> Function<V,R> compose(Function<? super V,? extends T> before) -返回一个组合函数,该函数首先应用 before 函数的输入,然后将此函数应用于结果。

    如你所见, Predicate 具有创建复杂条件的有用方法,与在常规 if 声明,鉴于 Function 具有支持简单链接的方法。

        4
  •  2
  •   ACV    6 年前

    Predicate 只能返回 boolean (结果 test() )当 Function 执行转换并可以返回任何内容(结果 apply() )

    谓语 用于测试条件。

    功能 用于进行转换。

        5
  •  1
  •   Nathaniel Pisarski    6 年前

    其实没什么区别。

    理论上,两者之间不应该有任何功能上的区别 Predicate<T> Function<T, Boolean> . 一 Predicate 只是一个函数,它接受某种类型的对象并返回一个布尔值。一 Function 是一个泛化,它可以返回任何类型,而不仅仅是 Boolean s。

    在Java本身中可能有实现细节的不同细节,但是它们在理论上应该是相同的。

    例如,如果一个接口只能接受 Predicate<String> ,不是 Function<String, Boolean .

        6
  •  1
  •   marsouf    6 年前

    从技术角度来看, Predicate<T> 只是一个函数 T 返回布尔原语结果。但是,从使用的角度来看, 谓词<t> 完全不同于 Function<T, Boolean> .

    我们使用 谓词<t> 为了执行过滤操作,例如,在流管道中,我们采用 Stream<T> 大小 n ,使用 谓词<t> 得到小于或等于 n . 同时,A 函数<t,布尔值> 在流中,管道用于执行映射操作以转换 流<t> 变成一个 Stream<Boolean> .

    如你所见, 谓词<t> 和A 函数<t,布尔值> 技术上是相同的(忽略包装 Boolean 为了简单起见),但是当放到特定的上下文(例如流管道)中时,情况完全不同,因为它们中的每一个都扮演着不同的角色。