Java: установить коллекцию<E>, где элементы идентифицируются по классу
Мне нужна коллекция Set, где ее предметы будут идентифицироваться по классу предметов. Что-то вроде ReferenceIdentityMap
из коллекций Appache, но в области классов, т.е. два разных экземпляра одного и того же класса должны быть идентифицированы как одинаковые в этой коллекции.
Вы знаете, это нарушение equals()/hashCode()
принцип идентичности, но при случайном использовании это имеет смысл.
Я сделал это в простой поддержке класса с Map<Class<? extends E>, E>
, но из-за простоты не реализует Set<E>
, Там может быть более элегантное решение, декоратор любой Set<E>
было бы замечательно.
Есть ли какая-либо реализация такой коллекции (Apache/Google/ что-то /... Collections)?
3 ответа
Вы хотите переопределить значение 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>>
затем.
Как насчет расширения 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;
}
}
Вы можете создать класс Comparator и создать свой набор с учетом этого. Единственное условие, которое вы не должны нарушать, состоит в том, что для каждых двух элементов, которые вы пытаетесь добавить, сравнение (e1, e2) не должно выдавать исключение ClassCastException - это означает, что каждые два члена, которые вы пытаетесь вставить, должны быть сопоставимы.
Сам класс компаратора должен смотреть только на классы объектов, поэтому он будет безопасным.
Проверьте конструктор здесь.