来自函数引用的谓词(布尔类型)

时间:2018-01-30 14:56:22

标签: java java-8 predicate functional-interface

我需要使用基于布尔函数的谓词来组合流操作。通过将方法的参数重新抛出为谓词找到了一种解决方法,如下所示:

public <T> Predicate<T> pred(final Predicate<T> aLambda) {
    return aLambda;
}

public List<String> foo() {
    return new ArrayList<String>().stream() //of course, this does nothing, simplified
            .filter(pred(String::isEmpty).negate())
            .collect(Collectors.toList());
}

&#39; pred&#39;方法似乎什么都不做,但不是这样:

public List<String> foo() {
    return new ArrayList<String>().stream() 
            .filter((String::isEmpty).negate()) 
            .collect(Collectors.toList());
}

也不是任何内联转换:

public List<String> foo() {
    return new ArrayList<String>().stream() 
            .filter(((Predicate)String::isEmpty).negate())
            .collect(Collectors.toList());
}

似乎有效。失败并出现错误

  

此表达式的目标类型必须是功能接口

&#39; pred(...)&#39;花哨转换发生了什么?方法

3 个答案:

答案 0 :(得分:7)

您可以编写实用程序方法:

class PredicateUtils {

    public static <T> Predicate<T> not(Predicate<T> predicate) {
        return predicate.negate();
    }

}

并按如下方式使用:

.filter(not(String::isEmpty))

我认为它比投射到Predicate<T>

更具可读性
.filter(((Predicate<String>)String::isEmpty).negate())

虽然我会选择一个简单的lambda:

s -> !s.isEmpty()
  

pred(...)方法中的奇特转换是什么?

您已指定了一个上下文 - 要使用的类型。例如,String::isEmpty可以是Function<String, Boolean>Predicate<String>,或@FunctionalInterface,或其他内容。

您明确表示您期待Predicate<T>,并且您将返回Predicate<T>的实例。编译器现在能够确定您要使用的类型。

答案 1 :(得分:5)

您可以使用

((Predicate<String>) String::isEmpty).negate()

(注意使用正确的通用类型)

或(首选):

s -> !s.isEmpty()

更简单易读。

答案 2 :(得分:2)

你的第三个版本几乎有效:

Arrays.<String>asList("Foo", "Bar", "").stream() 
        .filter(((Predicate<String>)String::isEmpty).negate())
        .collect(Collectors.toList());

这似乎编译得很好。