I recently work on a project that heavily using collection filter function provided by Guava,but I found something like this won't produce the expected behavior:
Predicate<ProductClassDTO> secLevelPredicate = new Predicate<ProductClassDTO>() {
@Override
public boolean apply(ProductClassDTO pcLevel2) {
if (pcLevel2.get开发者_如何学运维FatherNodeSid() != null)
return pcLevel2.getFatherNodeSid() == dto.getSid();
else
return false;
}
};
dto object is an object in the outer loop but still reachable.
The return of that apply method is never get out with True,but if I replace the dto.getSid() with the real number like 1740 which is a father node number get from db, the outcome is fine.
So I figure that I can not evaluate variable in apply()?
I notice apply() javadoc has a line saying :
Its execution does not cause any observable side effects
Should this be the key to this problem?
It should be fine - although dto
will need to be a final variable if this is within a method and dto
is a local variable.
Is it possible that dto.getSid()
returns an Integer
and the problem is that it's just comparing the references instead of values? You may be able to make the code neater and correct just by using:
@Override
public boolean apply(ProductClassDTO pcLevel2) {
return Objects.equal(pcLevel2.getFatherNodeSid(), dto.getSid());
}
Rather than having your final
variable read inside of your anonymous class, you're better off limiting scope as much as possible, and not forcing scope to "bleed" with final
variables.
In fact, the Guava designers anticipated this, and want you to avoid using final
variables in this way, and gave you the tools to avoid it. In this case, it is a combination of Predicates.equalTo
and Predicates.compose
. I think what you're looking for is:
Predicate<ProductClassDTO> secLevelPredicate = Predicates.compose(
Predicates.equalTo(dto.getSid()),
new Function<ProductClassDTO, Long>() {
public Long apply(ProductClassDTO pcLevel2) {
return pcLevel2.getFatherNodeSid();
}
}
);
精彩评论