2011-10-17 57 views
3

我需要根據其他集合的內容篩選集合。通常,我會使用Collection.retainAll()方法。

不幸的是,我處理的域對象的相等性是相當不穩定的,這取決於比較上下文。因此,我不能依靠equals/hashCode

我的下一個反應是使用自定義Comparator,但我無法找到任何支持我想法的方法。實現這些功能不是問題,但我想在這裏重新發明輪子。

我錯過了API中的某些東西嗎?其他框架(不是太深奧)像普通人也是受歡迎的。
如果沒有,那麼什麼樣的優化會讓我的直接impl(通過在n^2中遍歷兩個集合中的所有項來創建兩個集合中的所有對象的列表)是一個好的方法?是否有自定義比較器的retainAll()的實現?

回答

3

建議使用Guava's filter。另一種方法是推出自己的retainAllBy(sourceCollection, Comparator)

+0

+1另一個番石榴解決方案,可能比我的 –

+0

更好,可以通過用Predicate包裝集合然後過濾來完成。聽起來不錯。謝謝 – kostja

1

我錯過了API中的一些東西嗎?

有沒有在Java集合框架,通過別的那麼標準equals實施做了retainAll


強烈取決於你的用例,你可以這樣來做:

創建一個包裝對象,可以纏繞你的對象,但與equals方法需要。然後使用該包裝來做retainAll之後,您需要從結果集合中打開對象。

但這種方式有兩個缺點:

  • 大量的對象將被創建
  • 如果包裝的equals方法仍然是有效的它只能工作正確的equals方法中的java doc for equals方法上。
+0

謝謝,我幾乎可以肯定收集/ s API本身,但只是不能相信它:)也許還有另一種可能性(像公用或像這樣的)。我更新了這個問題以擴展到其他庫文件 – kostja

+0

@kostja:你可以繼承一個集合並覆蓋它的retainAll方法... – Powerlord

1

Guava對這個問題,Equivalence概念有一個麻煩的解決方案。使用Equivalence.wrap()將對象包裝爲等價對象,將包裝的版本存儲在集合中,從而使集合使用自定義的equals/hashcode邏輯。

我(和其他人)要求Equivalence-based sets and maps,但不幸的是,番石榴團隊建議應採取上述路線。

+0

+1:這是我在編寫時尋找的API在覈心java中沒有支持 – Ralph

+1

聽起來相當複雜的,讓我感覺很好,使用我生鏽的n^2迭代方法;)謝謝。番石榴似乎真的值得努力。 – kostja