Tom*_* F. 8 java predicate java-8 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());
}
Run Code Online (Sandbox Code Playgroud)
'pred'方法似乎无能为力,但不是这样:
public List<String> foo() {
return new ArrayList<String>().stream()
.filter((String::isEmpty).negate())
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
也没有任何内联转换:
public List<String> foo() {
return new ArrayList<String>().stream()
.filter(((Predicate)String::isEmpty).negate())
.collect(Collectors.toList());
}
Run Code Online (Sandbox Code Playgroud)
似乎工作.失败了
此表达式的目标类型必须是功能接口
在'pred(...)'方法中,花式转换发生了什么?
你可以写一个实用工具方法:
class PredicateUtils {
public static <T> Predicate<T> not(Predicate<T> predicate) {
return predicate.negate();
}
}
Run Code Online (Sandbox Code Playgroud)
并按如下方式使用:
.filter(not(String::isEmpty))
Run Code Online (Sandbox Code Playgroud)
我相信它比铸造更具可读性Predicate<T>:
.filter(((Predicate<String>)String::isEmpty).negate())
Run Code Online (Sandbox Code Playgroud)
虽然我会选择一个简单的lambda:
s -> !s.isEmpty()
Run Code Online (Sandbox Code Playgroud)
该
pred(...)方法中发生了什么奇特的转换?
您已指定了上下文 - 要使用的类型.例如,a String::isEmpty可以是a Function<String, Boolean>,or Predicate<String>,或my @FunctionalInterface,或其他.
你清楚地说你期待一个Predicate<T>,你会返回一个实例Predicate<T>.编译器现在能够确定您要使用的类型.
您可以使用
((Predicate<String>) String::isEmpty).negate()
Run Code Online (Sandbox Code Playgroud)
(注意使用正确的通用类型)
或(首选):
s -> !s.isEmpty()
Run Code Online (Sandbox Code Playgroud)
这更简单,更易读.
| 归档时间: |
|
| 查看次数: |
2461 次 |
| 最近记录: |