I need Set collection, where its items will be identified by items class. Something like ReferenceIdentityMap from Appache Collections, but on class scope i.e. two different instances of same class must be identified as same in this collection.
You know, it is a violation of equals()/hashCode() identity principle but in occasional use it makes sense.
I have done this in simple class backing with Map<Class<? extends E>, E>, but due to simplicity it doesn't implement Set<E>. There may be a more elegant solution, decorator of any Set<E> would be great.
Is there any implementation of such collection there (Apache/Google/something/... Collections)?
You wish to override the meaning of equals() / hashCode() for your set members. The cleanest way to do this, I imagine, 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();
}
}
You would create a Set<Wrapper<E>> then.
How about extending HashSet and overriding just the add(..) method, putting object.getClass() instead of the object itself in an inner Set<Class<? extends E>>, and if it succeeds, adding the item itself. Something like
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With