如何使用谓词函数过滤Java中的列表?
考虑以下代码:如何使用谓词函数过滤Java中的列表?,java,generics,collections,contravariance,Java,Generics,Collections,Contravariance,考虑以下代码: ICondition searchCondition, scopeCondition... List<ICondition> filtered = CollectionUtil.filter( Arrays.asList(searchCondition, scopeCondition), CollectionUtil.isNonNull); 为什么不能将第二个谓词与filter()一起使用?尝试泛化isNonNull: private static
ICondition searchCondition, scopeCondition...
List<ICondition> filtered = CollectionUtil.filter(
Arrays.asList(searchCondition, scopeCondition),
CollectionUtil.isNonNull);
为什么不能将第二个谓词与
filter()
一起使用?尝试泛化isNonNull
:
private static class IsNonNullPredicate<T> implements Predicate<T> {
public boolean apply(T item) {
return null != item;
}
}
私有静态类IsNonNullPredicate实现谓词{
公共布尔应用(T项){
返回null!=项目;
}
}
现在,您可以通过util类中的泛型方法而不是常量返回它
public <T> Predicate<T> isNonNull() {
return new IsNonNullPredicate<T>();
}
公共谓词isNonNull(){
返回新的IsNonNullPredicate();
}
或者,只需对存储实例执行未经检查的强制转换,而不是每次创建一个新实例:
private final Predicate isNotNullPredicate = new IsNonNullPredicate();
public <T> Predicate<T> isNonNull() {
return (Predicate<T>) isNotNullPredicate;
}
private final Predicate isNotNullPredicate=new IsNonNullPredicate();
公共谓词isNonNull(){
返回(谓词)isNotNullPredicate;
}
这就是Java集合库中的
Collections
类在其实用方法中为泛型提供支持所做的。1.5之前有集合。添加泛型后的空列表将返回列表。但是,这不会返回一个适当泛化的列表,因此添加了集合。emptyList()
以返回适合调用上下文的任何类型的列表。看起来您的过滤器
函数的谓词
参数不是正确的反变量。尝试按如下方式重写它:
public static <T> List<T> filter(Collection<? extends T> source,
Predicate<? super T> predicate)
{
final List<T> result = new ArrayList<T>(source.size());
for (T element: source)
if (predicate.apply(element))
result.add(element);
return result;
}
公共静态列表过滤器(Collection不确定,但尝试将isNotNull更改为返回+1,我的答案修复了OP的直接问题和一般情况,但实际上筛选方法不需要像您所说的那样接受确切的谓词
。谢谢你们两位。我很担心在没有编译您的示例或我提出的解决方案的情况下键入它,bu显然,这个想法是不够的。请务必回来,并注意它是否如书面所示。谢谢,我很肯定这也会起作用,我想我会在离开电脑一小时后到达这里!
public static <T> List<T> filter(Collection<? extends T> source,
Predicate<? super T> predicate)
{
final List<T> result = new ArrayList<T>(source.size());
for (T element: source)
if (predicate.apply(element))
result.add(element);
return result;
}