我可以在谓词应用方法中评估变量吗?

时间:2011-08-30 10:04:49

标签: java guava

我最近在一个大量使用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有一句话:

  

它的执行不会导致任何可观察到的副作用

这应该是解决这个问题的关键吗?

2 个答案:

答案 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.equalToPredicates.compose的组合。我想你要找的是:

Predicate<ProductClassDTO> secLevelPredicate = Predicates.compose(
    Predicates.equalTo(dto.getSid()),
    new Function<ProductClassDTO, Long>() {
        public Long apply(ProductClassDTO pcLevel2) {
            return pcLevel2.getFatherNodeSid();
        }
    }
);