3

我需要 Set 集合,其中的项目将由项目类标识。类似于Appache CollectionsReferenceIdentityMap的东西,但在类范围内,即同一类的两个不同实例必须在此集合中标识为相同。

你知道,这违反了equals()/hashCode()身份原则,但偶尔使用它是有道理的。

我已经在简单的类支持中做到了这一点Map<Class<? extends E>, E>,但由于简单,它没有实现Set<E>。可能有一个更优雅的解决方案,任何装饰器Set<E>都会很棒。

那里有这样的集合的实现吗(Apache/Google/something/... Collections)?

4

3 回答 3

1

如何HashSet仅扩展和覆盖该add(..)方法,object.getClass()而不是将对象本身放入 inner 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

您希望为您的集合成员覆盖 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>>then。

于 2010-03-15T11:06:58.987 回答
-1

您可以创建一个 Comparator 类并记住它来构建您的集合。您不能违反的唯一条件是,对于您尝试添加的每两个元素,compare(e1, e2) 不应抛出 ClassCastException - 这意味着您尝试插入的每两个成员都应该是可比较的。

比较器类本身应该只查看对象的类,所以它是安全的。

在这里查看构造函数。

于 2010-03-15T23:01:25.357 回答