Java: set <E>, where elements are identified by its class
I need a Set collection where its elements will be identified by element classes. Something like ReferenceIdentityMapfrom Application Collections , but in the scope of a class, that is, two different instances of the same class should be identified as the same in this collection.
You know, this is a violation of the principle of identity equals()/hashCode(), but if used it makes sense.
I did this in simple class support using Map<Class<? extends E>, E>, but because of simplicity, it does not implement Set<E>. Perhaps there will be a more elegant solution, any decorator Set<E>will be great.
Is there any implementation of such a collection there (Apache / Google / something / ... Collections)?
You want to override the equals () / hashCode () value for your set members. The cleanest way to do this, I suppose, is to use a wrapper class:
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();
}
}
Then you will create Set<Wrapper<E>>.
How about expanding HashSetand overriding only the method add(..), placing object.getClass()instead of the object itself in the internal Set<Class<? extends E>>, and if it succeeds, adding the element itself. Sort of
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;
}
}