Java: установить <E>коллекцию, где элементы идентифицируются по классу - PullRequest
3 голосов
/ 15 марта 2010

Мне нужна коллекция Set, где ее предметы будут идентифицироваться по классу предметов. Что-то вроде ReferenceIdentityMap из Коллекции Appache , но в области действия класса, т.е. два разных экземпляра одного и того же класса должны быть идентифицированы как одинаковые в этой коллекции.

Вы знаете, это нарушение equals()/hashCode() принципа идентичности, но при случайном использовании это имеет смысл.

Я сделал это в простой поддержке классов с Map<Class<? extends E>, E>, но из-за простоты он не реализует Set<E>. Может быть более элегантное решение, отлично подойдет любой декоратор Set<E>.

Есть ли реализация такой коллекции (Apache / Google / что-то / ... Collections)?

Ответы [ 3 ]

1 голос
/ 15 марта 2010

Вы хотите переопределить значение 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>>.

1 голос
/ 15 марта 2010

Как насчет расширения 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;
    }
}
0 голосов
/ 16 марта 2010

Вы можете создать класс Comparator и создать свой набор с учетом этого. Единственное условие, которое вы не должны нарушать, состоит в том, что для каждых двух элементов, которые вы пытаетесь добавить, сравнение (e1, e2) не должно вызывать ClassCastException - это означает, что каждые два члена, которые вы пытаетесь вставить, должны быть сопоставимы.

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

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

...