我最近在一个大量使用Guava提供的集合过滤功能的项目上工作,但我发现这样的事情不会产生预期的行为:
Predicate<ProductClassDTO> secLevelPredicate = new Predicate<ProductClassDTO>() {
@Override
public boolean apply(ProductClassDTO pcLevel2) {
if (pcLevel2.getFatherNodeSid() != null)
return pcLevel2.getFatherNodeSid() == dto.getSid();
else
return false;
}
};
dto object是外部循环中的一个对象,但仍然可以访问。
应用方法的返回永远不会出现True,但是如果我用实数来替换dto.getSid(),如1740这是从db获取的父节点数,结果很好。
所以我认为我无法在apply()中评估变量?
我注意到apply() javadoc有一句话:
它的执行不会导致任何可观察到的副作用
这应该是解决这个问题的关键吗?
答案 0 :(得分:5)
应该没问题 - 如果dto
在方法中并且dto
是局部变量,则dto.getSid()
需要是最终变量。
Integer
是否有可能返回@Override
public boolean apply(ProductClassDTO pcLevel2) {
return Objects.equal(pcLevel2.getFatherNodeSid(), dto.getSid());
}
,问题是它只是比较引用而不是值?您可以通过使用:
{{1}}
答案 1 :(得分:1)
您最好不要在匿名类中读取final
变量,而是最好尽可能地限制范围,而不是强制范围与final
变量“流血”。
事实上,Guava设计师对此有所期待,并希望您避免以这种方式使用final
变量,并为您提供避免它的工具。在这种情况下,它是Predicates.equalTo
和Predicates.compose
的组合。我想你要找的是:
Predicate<ProductClassDTO> secLevelPredicate = Predicates.compose(
Predicates.equalTo(dto.getSid()),
new Function<ProductClassDTO, Long>() {
public Long apply(ProductClassDTO pcLevel2) {
return pcLevel2.getFatherNodeSid();
}
}
);