为什么Java 8的谓词< T>扩展函数< T,Boolean> [英] Why doesn't Java 8's Predicate<T> extend Function<T, Boolean>

查看:282
本文介绍了为什么Java 8的谓词< T>扩展函数< T,Boolean>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我编写Predicate接口,我想在接口中编码,它只是一个返回原始布尔值的函数,如下所示:

  @FunctionalInterface 
public interface Predicate< T>扩展Function< T,Boolean> {

布尔测试(T t);

@Override
default布尔值apply(T t){
return Boolean.valueOf(test(t));




$ b我想知道,是否有一个引人注目的原因Java 8 API设计者选择将Predicate与Function完全分开?有没有证据表明他们认为这样做,并决定反对呢?对于消费者(可以是Function ),供应商(Function )和基本函数如IntFunction(Function )的所有其他特殊功能接口,我想也是类似的问题。



我没有深入彻底地思考过这一切的后果,所以我可能错过了一些东西。



编辑:一些答案ephasize申请和测试之间的语义区别。我并不是说我不赞赏这种区别,我同意这种区别是有益的。我不明白的是,为什么一个谓词不是一个函数,就像例如一个List是一个Collection或Double是一个数字,它是一个Object。



如果Predicate(以及所有其他特殊的通用功能接口,如Consumer,Supplier,IntUnaryOperator等等)与函数有这种关系,它将允许人们在需要函数参数的地方使用它(想到的是与其他函数组合,例如调用myFunction.compose(myPredicate)或避免编写几个专门的函数一个API,当这样的自动(un)拳击实现,如上所述就足够了)编辑2:看看openjdk lambda项目我发现原始函数接口用于扩展函数直到 Brian Goetz于2012-12-19发表的这个提交 。在那个时候,我找不到在任何lambda-dev或JSR专家组邮件列表上发生更改的具体原因。 解决方案

p> Predicate< T> 中的方法返回布尔值函数< T,Boolean> 中的方法返回 Boolean 。他们不一样。虽然存在自动装箱,但Java方法在原语执行时不会使用包装类。此外,还有一些不同之处,比如布尔值可以是 null ,而布尔值不能。



消费者< T> 的情况下,它更加不同。 Consumer< T> 中的方法返回类型为 void ,这意味着它可以使用<$ c隐式返回或返回$ c> return; ,但是函数< T,Void> 中的方法必须使用返回null; code>明确。


If I wrote the Predicate interface, i'd want to encode in the interface the fact that it's just a function that returns a primitive boolean, like this:

@FunctionalInterface
public interface Predicate<T> extends Function<T, Boolean> {

    boolean test(T t);

    @Override
    default Boolean apply(T t) {
        return Boolean.valueOf(test(t));
    }
}

I was wondering, is there a compelling reason Java 8 API designers chose to keep the Predicate completely separate from Function? Is there some evidence that they considered doing so and decided against it? I guess similar question goes for all the other 'special' functional interfaces like Consumer (could be Function<T, Void>), Supplier (Function<Void, T>) and primitive functions like IntFunction (Function<Integer, T>).

I haven't thought very deeply and thoroughly about all the ramifications of this, so I'm probably missing something.

EDIT: Some of the answers ephasize the semantic distinction between apply and test. I'm not saying I don't appreciate the distinction, and I agree that it's beneficial to have this distinction. What I don't understand is why a Predicate is nevertheless not also a Function in the same way as e.g. a List is a Collection or Double is a Number, which is an Object.

If Predicate (and all the other special generic functional interfaces, such as Consumer, Supplier, IntUnaryOperator etc.) had this relation with Function, it would allow one to use it in place where Function parameter is expected (what comes to mind is composition with other functions, e.g. calling myFunction.compose(myPredicate) or to avoid writing several specialized functions in an API when such auto(un)boxing implementation as described above would be sufficient)

EDIT 2: Looking at openjdk lambda project I found that primitive functional interfaces used to extend Function up until this commit from Brian Goetz on 2012-12-19. I couldn't find specific reasons for the change on any of the lambda-dev or JSR experts group mailing lists around that time.

解决方案

The method in Predicate<T> returns boolean. The method in Function<T, Boolean> returns Boolean. They are not the same. Although there is autoboxing, Java methods don't use wrapper classes when primitives would do. Also, there are differences like Boolean can be null while boolean can't.

It's even more different in the case of Consumer<T>. The method in Consumer<T> has return type void, which means it can implicitly return or return using return;, but the method in Function<T, Void> must return using return null; explicitly.

这篇关于为什么Java 8的谓词&lt; T&gt;扩展函数&lt; T,Boolean&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆