Java:设置<e>集合,其中项目由其类</e>标识

时间:2010-03-15 10:44:42

标签: java collections apache-commons

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

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

我在使用Map<Class<? extends E>, E>的简单类支持中完成了此操作,但由于简单性,它未实现Set<E>。可能有一个更优雅的解决方案,任何Set<E>的装饰者都会很棒。

那里是否有任何此类集合的实现(Apache / Google / something / ... Collections)?

3 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:1)

您希望覆盖set成员的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>>

答案 2 :(得分:-1)

您可以创建一个Comparator类,并在构建您的集合时考虑到它。您必须不违反的唯一条件是,对于您尝试添加的每两个元素,比较(e1,e2)不应抛出ClassCastException - 这意味着您尝试插入的每两个成员应具有可比性。

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

查看构造函数here