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

2022-09-01 10:27:28

我知道这可能是一个关于SO的非常基本的问题,但我想知道Java8中的a和接口有什么区别?PredicateFunction

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


答案 1

和 之间的区别Predicate<T>Function<T, R>

首先,a 是严格意义上的布尔值函数:Predicate<T>

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

然而,对于一个来说,这不一定是正确的:Function<T, R>

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

后者使用任何类型的对象,就像启用一样,但返回类型可以有所不同Predicate<T>

和 的用例Predicate<T>Function<T, R>

的用例是当您需要一个函数来使用一个类型的参数并返回一个布尔值时。例如,您可能想要过滤元素流,从满足条件的流中找到第一个元素,或者检查满足某种条件的流中的元素是否存在,例如,等。Predicate<T>T.filter(predicate).findFirst()anyMatchnoneMatchallMatch

的用例是,当您需要一个函数来使用一个类型的参数并将其转换为类型时,例如,在调用 时可能。Function<T, R>TRstream.map(func)

代码片段说明:

关于您帖子中的示例片段,并且就它们所代表的内容而言是相同的,即它们都表示一个函数,它接受a并返回一个。但是,前者避免将返回值从 打包到,而后者则不这样做。Predicate<String>Function<String, Boolean>StringbooleanbooleanBoolean

也就是说,这并不一定意味着无论你在哪里可以使用a,你也可以使用a,反之亦然。Predicate<String>Function<String, Boolean>

例:

虽然编译:

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

在这种情况下,没有区别,它只对你可以申请的东西重要。例如,期望 a ,你不能传递 a,即使逻辑上它们做同样的事情。allMatchPredicateFunction