2011-10-17 1 views
3

私は他のコレクションの内容に従ってコレクションを掘り起こす必要があります。通常、私はCollection.retainAll()メソッドを使用していました。

残念ながら、私が扱うドメインオブジェクトの等価性は、比較コンテキストによってはかなり変動します。したがって、私はequals/hashCodeに頼ることはできません。

私の次の反射は、カスタムComparatorを使用することでしたが、私が気にしていたことをサポートする方法は見つかりませんでした。機能を実装することは問題ではありませんが、私はここでホイールを改革する気がします。

私はAPIで何かを見逃しましたか?コモンズのような他のフレームワーク(それほど難解ではない)も歓迎します。
もしそうでなければ、どちらの最適化をすればよいでしょうか(両方のコレクションのすべてのアイテムをn^2のすべてのアイテムに渡すことによって、両方のコレクション内のすべてのオブジェクトのリストを作成する)良いものになりますか?カスタムComparatorsでretainAll()の実装がありますか?

答えて

3

Guava's filterをご提案ください。代わりにあなたのロールを回すことですretainAllBy(sourceCollection, Comparator)

+0

もう1つのグアバ解決策は、おそらく私の –

+0

よりも優れています。これを行うには、Predicateでコレクションをラップしてからフィルタリングします。いいですね。ありがとうございました – kostja

1

APIで何か不足していますか?

何かによってretainAllを行うのJavaコレクションフレームワーク、標準のequals実装では何もありません。


は強くあなたのユースケースに応じて、あなたは、このようにそれを行うことができます。

が、あなたが必要とするequals方法では、あなたのオブジェクトの周りに巻き付け可能なラッパーオブジェクトを作成します。そして、そのラッパーを使用してretainAllを実行した後、結果のコレクションからオブジェクトをアンラップする必要があります。

しかし、この方法は、2つの欠点があります作成されるオブジェクトの

  • たくさん
  • ラッパーのequals方法がまだ有効である場合、それが唯一の正しい動作しないがjava doc for equals方法の面でequalsメソッドを。
+0

ありがとうございました。私は、Collection/s API自体についてほとんど確信していましたが、信じられませんでした:)別の可能性があります(コモンズやsthなど)。 – kostja

+0

@kostja:コレクションをサブクラス化し、そのretainAllメソッドをオーバーライドすることができます... – Powerlord

1

Guavaは、この問題に対する厄介な解決策を持っています。Equivalenceです。 Equivalence.wrap()を使用してオブジェクトを等価にラップし、ラップされたバージョンをコレクションに格納して、コレクションがカスタムequals/hashcodeロジックを使用するようにします。

I(および他の者)がEquivalence-based sets and mapsを要求しましたが、残念なことに、Guavaチームは、代わりに上記のルートを取るべきだと提案します。

+0

+1:それは、コアJavaではサポートされていないと書いている間に探していたAPIでした – Ralph

+1

複雑で、私の錆びたn^2の反復方法を使用して、かなり上手く感じられます;)ありがとう。 Guavaは本当に努力の価値があるようだ。 – kostja

関連する問題