Reputation: 2374
I have a Set
of objects and I don't want to allow to store there more than one instance of any class. Which solution is the best:
hashCode
to return constant and equals
to return o != null && o.getClass() == getClass()
Set
(almost like first option)Upvotes: 1
Views: 198
Reputation: 198341
Guava provides ClassToInstanceMap
, which is already checked for safety, tested, and the like. It's like a Map<Class<T>, T>
, but it deals with all the type system stuff already.
Upvotes: 0
Reputation: 43504
I would use a Map<Class<? extends T>, T>
for it.
Example implementation:
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);
}
}
Example usage:
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);
}
Outputs something like:
{class java.lang.String=hello, class java.lang.Integer=1234}
Upvotes: 4
Reputation: 114817
You could invent implement a small wrapper class and store that instead of the instances:
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());
}
}
As equality is defined via the Class instances, a set will only accept one instance of any class.
Upvotes: 0
Reputation: 30465
Use a HashMap. Before adding an object, get its class (using reflection) and check whether it is already a key in the HashMap.
Upvotes: 1