Java8中谓词和函数接口的区别是什么?

Java8中谓词和函数接口的区别是什么?,java,function,java-8,predicate,Java,Function,Java 8,Predicate,我知道这可能是一个非常基本的问题,但我想知道Java8中谓词和函数接口之间的区别是什么 Predicate<String> predicateTest = (s)-> s.length() > 5; System.out.println(predicateTest.test("Predicate")); Function<String, Boolean> functionTest = str -> str.length()> 5;

我知道这可能是一个非常基本的问题,但我想知道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"));
谓词test=(s)->s.length()>5;
System.out.println(谓词测试(“谓词”);
函数functionTest=str->str.length()>5;
System.out.println(functionTest.apply(“函数”));

在我的示例中,两者都返回
true
。唯一的问题是调用的方式不同?

在这种情况下没有区别,它只关系到您可以应用到的内容。因此,例如
allMatch
需要一个
谓词
,您不能传递
函数
,即使它们在逻辑上做相同的事情

真的没什么区别。
从理论上讲,
谓词
函数
之间不应该有任何功能上的区别。
谓词
只是一个函数,它接受某种类型的对象并返回布尔值。
函数
是一种泛化,它可以返回任何类型,而不仅仅是
布尔值

Java本身可能有一些实现细节使它们与众不同,但在理论上它们应该是相同的

例如,如果接口只能接受
谓词
,而不能接受
谓词
函数
首先,
谓词
严格来说是一个布尔值函数:

         _ _ _ _ _ _ _ 
        |             |
  T --> |  predicate  | --> boolean
        |_ _ _ _ _ _ _|   
然而,对于
函数
,这不一定是正确的:

后者使用任何类型的对象,就像
谓词
启用一样,但返回类型可能有所不同

谓词
函数的用例
谓词
的用例是当您需要一个使用一个类型为
T
的参数并返回布尔值的函数时。e、 g.在这种情况下,可能需要筛选元素流,从满足
.filter(predicate).findFirst()
等条件的流中查找第一个元素,或者从满足
anyMatch
noneMatch
等特定条件的流中检查是否存在元素,
allMatch

Function
的用例是当您需要一个函数,该函数使用一个
T
类型的参数,并将其转换为
R
类型,例如,调用
stream.map(func)
时可能会用到该类型

对代码片段的解释: 关于您文章中的示例代码段,
谓词
函数
在它们所表示的内容方面是相同的,即它们都表示一个函数,它接受一个
字符串
,并返回一个
布尔值
。但是,前者避免将返回值从
boolean
装箱到
boolean
,而后者则没有

这就是说,这并不一定意味着无论在哪里可以使用
谓词
,也可以使用
函数
,反之亦然

示例:

虽然这样做可以编译:

Predicate<String> predicate = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(predicate);
谓词=p->p.length()==21;
Stream-Stream=stringList().Stream().filter(谓词);
这并不是:

Function<String, Boolean> function = p -> p.length() == 21;
Stream<String> stream = stringList().stream().filter(function);
Predicate<String> predicate = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(predicate);
Function=p->p.length()==21;
Stream=stringList().Stream().filter(函数);
反之亦然:

虽然这样做有效:

Function<String, Boolean> function = p -> p.length() == 21;
Stream<Boolean> stream = stringList().stream().map(function);
Function=p->p.length()==21;
Stream-Stream=stringList().Stream().map(函数);
这并不是:

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

A
谓词
只能返回一个
布尔值(
测试()的结果
),而
函数
执行转换,并且可以返回任何值(
应用()的结果

谓词
用于测试条件


一个
函数
用于进行转换。

Aominè的回答涵盖了基本的区别。我想补充的是,这两个接口还具有不同的专用默认方法,即可以在任何实现类上调用的方法:


    • 谓词和(Predicate从技术角度来看,
      谓词
      只是一个函数,它接受
      T
      并返回布尔基元结果。然而,从使用角度来看,
      谓词
      函数
      是完全不同的概念

      我们使用
      谓词
      执行过滤操作,例如,在流管道中,我们取大小为
      n
      ,使用
      谓词
      对其进行过滤,以获得大小小于或等于
      n
      的流。同时,流管道中的
      函数
      用于执行映射操作打开可将
      转换为


      正如您所看到的,
      谓词
      函数
      在技术上是相同的(为了简单起见,忽略包装器
      布尔值
      ),但放在特定上下文中(例如流管道),这是一个完全不同的故事,因为他们每个人都扮演着不同的角色。

      虽然这是一篇老文章,但我将为新手总结他们之间的差异

      谓词:要实现条件检查我们应该使用谓词

      函数:要执行某些操作并返回某些结果我们应该使用函数

      谓词:谓词可以接受一个表示输入类型或参数类型的类型参数

      函数:函数可以接受两个类型参数,第一个表示输入类型参数类型,第二个表示返回类型

      谓词:Predi