2

コレクションの初期化時にメンバーオブジェクトが「等しい」かどうかを判断するための戦略を受け入れることができる独自のJavaコレクションを利用したいと思います。

これを行う必要があるのは、このコレクションに追加する必要があるクラスの equals メソッドが、他の (より適切な) 機能を満たすために既に実装されているためです。特定のケースでは、このコレクション インスタンスの一意性の基準は、equals メソッドでチェックされる多数の変数とは対照的に、クラスの 1 つの変数のみをチェックする必要があります。異種のライブラリからオブジェクトを収集しているため、オブジェクトを装飾することは避けたいと思います。装飾のためにループするのはコストがかかります(コードが混乱する可能性があります)。

これは Set のJava 契約に違反するため、 Set ではないことは理解していますが、この問題は以前に発生したに違いないと感じています。GuavaまたはApache Collectionsが何かを提供していると考えましたが、運が悪いようです。このタイプの機能を提供する利用可能なライブラリを知っている人はいますか? 完全に別のソリューションを楽しまなければなりませんか?

4

3 に答える 3

3

Custom Comparator と TreeSet または TreeMap を使用できますか? または、キーに基準があるマップを使用しますか? HashSet は HashMap の単なるラッパーであるため、代わりにマップを使用すると、はるかにコストがかかります。

于 2013-01-10T17:10:43.340 に答える
1

それは実際には実用的ではありません。Cたとえば、同等と見なすクラスの2つのインスタンスについて考えてみます。

今あなたはします:

set.add(c1);
set.remove(c2);

その後、セットを空にする必要がありますか?.retainAll()、はどう.removeAll()ですか?

ここでの最善の策は、クラスをラップする独自のクラスを作成し、C委任する必要があるものをすべて削除し、このラッパークラスに実装.hashCode()してもらうことです.equals()(場合によってComparableはそれ自体も)。このようなクラスでは、古典的なセットやマップをそのまま使用できます。

于 2013-01-10T17:16:52.900 に答える
1

Guava には等価性があり、2 つのオブジェクトが等価かどうかを定義できます。

また、任意のオブジェクトをラップし、equals() および hashCode() を独自のものではなく、同等の実装に委譲する Equivalence.Wrapper もあります。

したがって、次のようなことができます。

public class MySet<T> implements Set<T> {

    private final Equivalence<T> equivalence;

    private final Set<Wrapper<T>> delegate = new HashSet<Wrapper<T>>();

    public MySet(Equivalence<T> equivalence) {
        this.equivalence = equivalence;
    }

    public boolean add(T t) {
        return delegate.add(equivalence.wrap(t));
    }

    // other Set methods

}
于 2013-01-10T17:23:07.990 に答える