首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java 8谓词

Java 8谓词
EN

Stack Overflow用户
提问于 2018-07-08 07:39:16
回答 2查看 1.2K关注 0票数 2

下面是一个以谓词作为参数的示例方法:

代码语言:javascript
复制
void processFields(List<WebDataField> fields, Predicate<WebDataField> predicate) {
    for (WebDataField webDataField : fields) {
        boolean expectedCondition = predicate.test(webDataField);
    }
}

我将上述功能称为:

代码语言:javascript
复制
processFields(fields, w -> w.getFieldName().length() > 5);

另一项职能:

代码语言:javascript
复制
public void doSomething(Object someObject,Predicate<T> predicateInstance){
    //doSomething method's code goes here
}

在调用端,方法doSomething()将被调用如下-

代码语言:javascript
复制
doSomething(someObjectInstance, Integer i-> i>10)

我检查了Java 8文档中的String/Integer/Object等,但是没有找到实现Predicate<T>接口的任何类。我不知道在我的Java 8教程系列中错过了什么,但是我无法得到这样的现象:

  1. 如果目标类型与谓词类没有直接联系,编译器如何允许lambda表达式?
  2. 上述两种情况的答案是否相同?
EN

回答 2

Stack Overflow用户

发布于 2018-07-08 07:43:26

lambda表达式(Integer i) -> i>1的值不是Integer,因此Integer不必实现Predicate才能将该lambda表达式传递给您的方法。

Integer是lambda表达式的参数i的类型。(Integer i) -> i>1可以表示具有单个方法的任何函数接口,该方法接受Integer参数并返回boolean。因此,它适合于Predicate<Integer>功能接口。

您的另一个lambda表达式- w -> w.getFieldName().length() > 5 -接受一个未指定类型的参数,并返回一个boolean。为了通过编译,编译器必须推断w的类型为具有getFieldName()方法的类或接口,该方法返回具有length()方法的某种类型的实例。当您将您的lambda表达式传递给您的processFields方法(它需要一个Predicate<WebDataField> )时,编译器可以推断该lambda表达式的参数w的类型是WebDataField

票数 1
EN

Stack Overflow用户

发布于 2018-07-08 08:36:58

回答第一个问题:

上面的lambda表达式i-> i>10是表示以下内容的更短的方法:

代码语言:javascript
复制
Predicate<Integer> predicate = new Predicate<Integer>() {

  @Override
  public boolean test(Integer i) {
    return i > 10;
  }
};

然后将用于下列用途:

代码语言:javascript
复制
Integer someObjectInstance = 1;
doSomething(someObjectInstance, predicate);

因此,目标类型(Integer)具有“与谓词的直接连接”。

接下来是第二个问题:

Predicate<T>上,T是一个通用类型参数。泛型类型参数只接受引用类型,而不接受基本类型。因此,Predicate<T> p始终必须有一个T类型的对象实例作为参数(您称之为someObjectInstance)。如果您想测试一个Integer,您可以这样做:

代码语言:javascript
复制
Integer someObjectInstance = 1;
doSomething(someObjectInstance, i-> i>10);

但是,如果尝试使用原语类型整数(int)调用该方法,则会出现语法错误:

代码语言:javascript
复制
int integer = 0;
worker.doSomething(integer, i -> i > 10); // The operator > is undefined for the argument type(s) Object, int

但是,可以通过显式提供泛型类型参数来帮助编译器。在本例中,它是Integer,对应的包装类型为int。这将因为自动拳击而起作用。

代码语言:javascript
复制
int integer = 0;
worker.<Integer> doSomething(integer, i -> i > 10);

但是对于"String/Integer/Object等.找不到实现谓词的任何类“。对于原语类型,有专用的谓词接口。例如:IntPredicate

但是他们并没有扩展Predicate<T>接口。这是不可能的,因为像IntPredicate extends Predicate<int>这样的定义是无效的。如上所述,int作为泛型类型参数是不可接受的。

要使用IntPredicate,可以声明一个方法

代码语言:javascript
复制
  public <T> void doSomething(int i, IntPredicate intPredicate) {
    // doSomething method's code goes here
  }

就这样叫它:

代码语言:javascript
复制
doSomething(integer, i -> i > 10);

要获得不同谓词接口的概述,请查看包java.util.function 参考文献

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51229829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档