2012-02-14 5 views
1

У меня есть Set объектов, и я не хочу позволять хранить там более одного экземпляра любого класса. Какое решение лучше:Набор для отдельных экземпляров классов

  • проверить, есть ли экземпляр данного класса в наборе (не кажется эффективным)
  • реализации hashCode вернуться постоянны и equals вернуть o != null && o.getClass() == getClass()
  • макияжа собственная реализация Set (почти как первый вариант)
  • что-нибудь еще? может быть, уже есть такой набор?
+0

Я не уверен, что ваш второй вариант будет работать. Разве вам не нужно было бы реализовать hashCode и равным для каждого отдельного класса в иерархии класса java. Или есть только определенные классы, которые вы хотите сохранить в своем наборе? –

ответ

5

Я использовал бы для этого Map<Class<? extends T>, T>. Реализация


Пример: использование

class SingleInstanceSet<T> { 

    Map<Class<? extends T>, T> map = new HashMap<Class<? extends T>, T>(); 

    public boolean add(T o) { 

     if (map.containsKey(o.getClass())) 
      return false; 

     map.put((Class<? extends T>) o.getClass(), o); 
     return true; 
    } 

    public T get(Class<? extends T> klass) { 
     return map.get(klass); 
    } 
} 

Пример:

public static void main(String[] args) { 
    ClassSet<Object> instances = new ClassSet<Object>(); 

    instances.add("hello"); 
    instances.add(1234); 
    instances.add("will not be added"); 

    System.out.println(instances.map); 
} 

Выходы что-то вроде:

{class java.lang.String=hello, class java.lang.Integer=1234} 
+0

Спасибо, я буду использовать его :) –

1

Используйте HashMap. Перед добавлением объекта, получите его класс (используя отражение) и проверьте, является ли он уже ключом в HashMap.

0

Вы можете изобрести реализовать небольшой класс-обертку и магазин, который вместо экземпляров:

public class InstanceWrapper { 
    private Object obj; 
    public InstanceWrapper(Object obj) { this.obj = obj; } 
    public Object getObject() { return obj; } 

    @Override 
    public boolean equals(Object other) { 
    return this.getClass().equals(other.getClass()); 
    } 

    @Override 
    public int hashCode() { 
    return this.getClass().hashCode()); 
    } 
} 

Как равенство определяется с помощью экземпляров класса, набор будет принимать только один экземпляр любого класса.

0

Guava предоставляет ClassToInstanceMap, что уже проверено на предмет безопасности, протестировано и тому подобное. Это похоже на Map<Class<T>, T>, но он касается всего типа системы.

Смежные вопросы