Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么';t爪哇8';s谓词<;T>;扩展函数<;T、 布尔值>;_Java_Lambda_Functional Programming_Predicate_Java 8 - Fatal编程技术网

Java 为什么';t爪哇8';s谓词<;T>;扩展函数<;T、 布尔值>;

Java 为什么';t爪哇8';s谓词<;T>;扩展函数<;T、 布尔值>;,java,lambda,functional-programming,predicate,java-8,Java,Lambda,Functional Programming,Predicate,Java 8,如果我编写了谓词接口,我希望在接口中对这一事实进行编码,即它只是一个返回原语布尔值的函数,如下所示: @FunctionalInterface public interface Predicate<T> extends Function<T, Boolean> { boolean test(T t); @Override default Boolean apply(T t) { return Boolean.valueOf(te

如果我编写了
谓词
接口,我希望在接口中对这一事实进行编码,即它只是一个返回原语
布尔值的函数,如下所示:

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

    boolean test(T t);

    @Override
    default Boolean apply(T t) {
        return Boolean.valueOf(test(t));
    }
}
@functioninterface
公共接口谓词扩展函数{
布尔检验(T);
@凌驾
默认布尔应用(T){
返回Boolean.valueOf(test(t));
}
}
我想知道,Java8API设计人员之所以选择将
谓词
函数
完全分离,是否有一个令人信服的原因?是否有证据表明他们考虑过这样做并决定反对?我猜类似的问题也适用于所有其他“特殊”功能接口,如
消费者
(可能是
功能
)、
供应商
功能
)和原始功能,如
IntFunction
功能

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

编辑:一些答案强调应用和测试之间的语义区别。我不是说我不欣赏这种区别,我同意这种区别是有益的。我不明白的是,为什么
谓词
列表
集合
双精度
数字
,它是
对象
,但在
中却不是
函数

如果
谓词
(以及所有其他特殊的通用功能接口,如
消费者
供应商
IntUnaryOperator
等)与
功能
有这种关系,则允许在预期
功能
参数的地方使用它(想到的是与其他函数的组合,例如调用
myFunction.compose(myPredicate)
或避免在API中编写多个专用函数,如果上述自动(非)装箱实现就足够了)


编辑2:查看openjdk lambda项目,我发现原始功能接口用于扩展
功能
。我找不到当时lambda开发人员或JSR专家组邮件列表发生变化的具体原因。

这不是对您问题的直接回答,但您会使用它做什么为了什么

考虑以下场景:您希望将true/false映射到分别为true和false的值列表

使用您的代码,您可以使用:

@FunctionalInterface
interface CustomPredicate<T> extends Function<T, Boolean> {
    boolean test(T value);

    @Override
    default Boolean apply(T t) {
        return test(t);
    }
}
@functioninterface
接口CustomPredicate扩展函数{
布尔检验(T值);
@凌驾
默认布尔应用(T){
回归试验(t);
}
}

List-stringList=new-ArrayList();
stringList.添加(“a”);
stringList.添加(“hg”);
添加(“dsl”);
stringList.添加(“sldi”);
stringList.添加(“ilsdo”);
stringList.add(“jlieio”);
CustomPredicate CustomPredicate=str->(str.length()>=3);
映射=stringList.stream()
.collect(collector.groupingBy(customPredicate));
但是,下面的内容告诉我,他们确实考虑过类似的事情,因为他们提供了分区方法:

List<String> stringList = new ArrayList<>();
stringList.add("a");
stringList.add("hg");
stringList.add("dsl");
stringList.add("sldi");
stringList.add("ilsdo");
stringList.add("jlieio");
Predicate<String> predicate = str -> (str.length() >= 3);
Map<Boolean, List<String>> mapping = stringList.stream()
        .collect(Collectors.partitioningBy(predicate));
List-stringList=new-ArrayList();
stringList.添加(“a”);
stringList.添加(“hg”);
添加(“dsl”);
stringList.添加(“sldi”);
stringList.添加(“ilsdo”);
stringList.add(“jlieio”);
谓词=str->(str.length()>=3);
映射=stringList.stream()
.collect(收集器.partitionby(谓词));
我能想到的一些原因是:

  • 谓词
    中使用
    apply()
    方法是不直观的,因为您只希望使用
    test()
    方法
  • 功能接口设计为只提供一种基本功能(不包括链接或逻辑操作),在您的情况下,
    CustomPredicate
    包含两种功能。这只会增加混乱

在我看来,
函数
只是泛型函数的定义。如果所有
函数接口
都将实现
函数
,那么唯一的抽象方法必须命名为
应用()
。在具体的
功能接口
过滤器文件
的上下文中,抽象方法
布尔接受(文件路径名)
是比
布尔应用(文件)
更好的名称


注释
@functionanterface
已经将一个接口标记为可作为
functionanterface
使用。让它们都实现一个基本接口,然后以通用方式处理它们是没有好处的。我看不出您何时会不关心
functionanterface的语义e> 提前让它们可以调用
apply

谓词
中的方法返回
boolean
函数
中的方法返回
boolean
。它们不一样。虽然有自动装箱,但Java方法在原语使用时不使用包装类。此外,还有e类似于
Boolean
的差异可以是
null
,而
Boolean
则不能


消费者
的情况下就更不一样了。
消费者
中的方法具有返回类型
void
,这意味着它可以使用
return;
隐式返回或返回,但是
函数
中的方法必须使用
return null;
显式返回。

不需要这种怀疑ous继承层次结构。这些功能接口是可相互更改的

Function<A,Boolean> f1=…;
Predicate<A>        p1=…;

Predicate<A>        p2=f1::apply;
Function<A,Boolean> f2=p1::test;
函数f1=…;
谓词p1=…;
谓词p2=f1::apply;
功能f2=p1::测试;
这在两个方向上都有效。那么为什么要有一个in
Function<A,Boolean> f1=…;
Predicate<A>        p1=…;

Predicate<A>        p2=f1::apply;
Function<A,Boolean> f2=p1::test;