3

Setコレクションが必要です。そのアイテムはitemsクラスによって識別されます。AppacheコレクションのようなものReferenceIdentityMapですが、クラススコープでは、つまり、同じクラスの2つの異なるインスタンスをこのコレクションで同じものとして識別する必要があります。

ご存知のとおり、これはequals()/hashCode()アイデンティティの原則に違反しますが、時折使用することは理にかなっています。

私はこれを単純なクラスバッキングで行いましMap<Class<? extends E>, E>たが、単純さのために実装していませんSet<E>。よりエレガントな解決策があるかもしれません、どんなデコレータSet<E>も素晴らしいでしょう。

そこにそのようなコレクションの実装はありますか(Apache / Google / something / ...コレクション)?

4

3 に答える 3

1

セットメンバーのequals()/ hashCode()の意味をオーバーライドしたいとします。これを行う最もクリーンな方法は、ラッパークラスを使用することだと思います。

class Wrapper<E> {

  private final E item;

  Wrapper(E item) {
    this.item = item;
  }

  E getItem() {
    return item;
  }

  public boolean equals(Object o) {
    if (!(o instanceof Wrapper)) {
      return false;
    }
    return getClass().equals(o.getClass());
  }

  public int hashCode() {
    return getClass().hashCode();
  }

}

その時を作成しますSet<Wrapper<E>>

于 2010-03-15T11:06:58.987 に答える
1

メソッドだけを拡張HashSetしてオーバーライドし、オブジェクト自体の代わりに内部に配置し、成功した場合はアイテム自体を追加するのはどうですか。何かのようなものadd(..)object.getClass()Set<Class<? extends E>>

public class ClassSet<E> extends HashSet<E> {
    private Set<Class<? extends E>> classSet = new HashSet<Class<? extends E>>();

    @Override
    public boolean add(E element) {
        if (classSet.add((Class<E>) element.getClass())) {
            return super.add(element); // this actually should always return true
        }
        return false;
    }
}
于 2010-03-15T10:48:31.630 に答える
-1

Comparatorクラスを作成し、それを念頭に置いてセットを作成できます。違反してはならない唯一の条件は、追加しようとする2つの要素ごとに、compare(e1、e2)がClassCastExceptionをスローしないことです。つまり、挿入しようとする2つのメンバーごとに比較可能である必要があります。

コンパレータクラス自体はオブジェクトのクラスのみを参照する必要があるため、安全です。

ここでコンストラクターをチェックしてください。

于 2010-03-15T23:01:25.357 に答える