我需要Set集合,其项目将由items类标识。类似于来自Appache Collections的ReferenceIdentityMap
,但是在类范围上,即在此集合中必须将同一类的两个不同实例标识为相同。
你知道,这违反了equals()/hashCode()
身份原则,但偶尔使用它是有道理的。
我在使用Map<Class<? extends E>, E>
的简单类支持中完成了此操作,但由于简单性,它未实现Set<E>
。可能有一个更优雅的解决方案,任何Set<E>
的装饰者都会很棒。
那里是否有任何此类集合的实现(Apache / Google / something / ... Collections)?
答案 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。