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 - это означает, что каждые два члена, которые вы пытаетесь вставить, должны быть сопоставимы.

Сам класс компаратора должен смотреть только на классы объектов, поэтому он будет безопасным.

Проверьте конструктор здесь.

Другие вопросы по тегам