我最近编写了一些代码,使用Guava库中的Predicates将复杂谓词组合为结果集的过滤器。我构建了一个名为PredicateFamily的类,它表示结果集中特定域的谓词集合。 Predicate系列还跟踪哪些谓词处于活动状态,以下方法应该构成来自所有单独族系列对象的单个谓词。
/**
* This method will AND together all the families and OR within the families
*
* @param families
* @return
*/
public static <E> Predicate<E> sumPredicates(Iterable<PredicateFamily<E>> families) {
Predicate<E> ret = Predicates.alwaysTrue();
for (PredicateFamily<E> family : families) {
if (family.hasActivePredicates()) {
// family.getActive() returns List<Predicate<E>>
Predicate<E> or = Predicates.or(family.getActive());
ret = Predicates.and(ret, or);
}
}
return ret;
}
当在本地运行它时,它可以游泳,但是当通过Hudson运行时,我遇到了以下令人困惑的错误:
[javac] symbol : method and(com.google.common.base.Predicate<T>,com.google.common.base.Predicate<T>)
[javac] location: class com.google.common.base.Predicates
[javac] ret = Predicates.and(ret, or);
[javac] ^
(该插入符号应位于Predicates.and的左括号内)
这是相当令人困惑的,据我所知,这应该满足Predicates的签名。检查Hudson我发现它在Ubuntu上的1.6.0_18下运行,编译器设置为1.5.0_22。
经过一番调查后,我们发现以下代码满足测试和编译,但是这样做会失去类型安全性。
public static <E> Predicate<E> sumPredicates(Iterable<PredicateFamily<E>> families) {
Predicate<E> ret = Predicates.alwaysTrue();
for (PredicateFamily<E> family : families) {
if (family.hasActivePredicates()) {
Predicate<E> or = Predicates.or(family.getActive());
ret = Predicates.and(Arrays.asList(ret, or));
}
}
return ret;
}
任何人都可以提出任何想法,为什么这不起作用?我真的很想知道。
编辑:仅供参考,这是在Guava r06下运行,但是从r07检查更改日志我没有看到Predicates.and的签名发生变化。
答案 0 :(得分:4)
有点晚了,但是......我相信这可以通过输入通用类型来解决:
ret = Predicates.<E>and( ...