2011-08-30 16 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(); 
     } 
    } 
);