我有Set
个对象,我不想允许在那里存储任何类的多个实例。哪种解决方案最好:
hashCode
以返回常量,equals
返回o != null && o.getClass() == getClass()
Set
(几乎像第一个选项)答案 0 :(得分:5)
我会使用Map<Class<? extends T>, T>
。
示例实施:
class SingleInstanceSet<T> {
Map<Class<? extends T>, T> map = new HashMap<Class<? extends T>, T>();
public boolean add(T o) {
if (map.containsKey(o.getClass()))
return false;
map.put((Class<? extends T>) o.getClass(), o);
return true;
}
public T get(Class<? extends T> klass) {
return map.get(klass);
}
}
使用示例:
public static void main(String[] args) {
ClassSet<Object> instances = new ClassSet<Object>();
instances.add("hello");
instances.add(1234);
instances.add("will not be added");
System.out.println(instances.map);
}
输出类似:
{class java.lang.String=hello, class java.lang.Integer=1234}
答案 1 :(得分:1)
使用HashMap。在添加对象之前,获取它的类(使用反射)并检查它是否已经是HashMap中的键。
答案 2 :(得分:0)
你可以 invent 实现一个小的包装类并存储而不是实例:
public class InstanceWrapper {
private Object obj;
public InstanceWrapper(Object obj) { this.obj = obj; }
public Object getObject() { return obj; }
@Override
public boolean equals(Object other) {
return this.getClass().equals(other.getClass());
}
@Override
public int hashCode() {
return this.getClass().hashCode());
}
}
由于通过类实例定义了相等性,因此一个集合只接受任何类的一个实例。
答案 3 :(得分:0)
Guava提供ClassToInstanceMap
,已经检查过安全性,测试等。它就像Map<Class<T>, T>
,但它已经处理了所有类型系统的东西。