2011-08-30 15 views
1

我最近上大量使用由番石榴提供收集过滤功能的项目工作,但我发现这样的事情就不会产生预期的行为:我可以评估谓词变适用方法

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对象是外部循环中的对象,但仍然可以访问。

该应用方法的返回值永远不会以True出现,但如果我将dto.getSid()替换为1740这样的实数,这是从db获得的父节点号,那么结果就很好。

所以我认为我不能在apply()中评估变量?

我注意到apply()的javadoc中有一行说:

它的执行不会引起任何可观察到的副作用

如果是这种关键,这个问题?

回答

5

它应该没问题 - 尽管dto需要是一个最终变量,如果这是在一个方法内,而dto是一个局部变量。

是否有可能dto.getSid()返回Integer并且问题在于它只是比较引用而不是值?您可以使代码更简洁正确只需使用:

@Override 
public boolean apply(ProductClassDTO pcLevel2) { 
    return Objects.equal(pcLevel2.getFatherNodeSid(), dto.getSid()); 
} 
+0

是的,我忘了我使用整型而不是值,一切都蛮好的,你给这里的改善是非常valuable.Appreciated。 – Lopakhin

1

而不是您的匿名类里面看了你的final变量,你最好还是限制范围尽可能和不要强迫范围与“final”变量“流血”。

事实上,番石榴设计师预计这一点,并希望您以这种方式避免使用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(); 
     } 
    } 
);