我需要使用基于布尔函数的谓词来组合流操作。通过将方法的参数重新抛出为谓词找到了一种解决方法,如下所示:
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;花哨转换发生了什么?方法
答案 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());
这似乎编译得很好。