2011-06-30 14 views
7

Próbuję zaimplementować bezpieczny heterogeniczny pojemnik do przechowywania list heterogenicznych obiektów.Wpisz bezpieczny, heterogeniczny wzorzec kontenera, aby przechowywać listy pozycji.

Widziałem kilka egzaminów bezpiecznego typu heterogenicznego typu kontenera (link), ale wszystkie z nich przechowują pojedynczy obiekt danego typu.

Mam tryed do wdrożenia go w następujący sposób:

public class EntityOrganizer { 

    private Map<Class<?>, List<Object>> entityMap = new HashMap<Class<?>, List<Object>>(); 

    public <T> List<T> getEntities(Class<T> clazz) { 
     return entityMap.containsKey(clazz) ? entityMap.get(clazz) : Collections.EMPTY_LIST; 
    } 

    private <T> void addEntity(Class<T> clazz, T entity) { 
     List<T> entityList = (List<T>) entityMap.get(clazz); 
     if(entityList == null) { 
      entityList = new ArrayList<T>(); 
      entityMap.put(clazz, (List<Object>) entityList); 
     } 
     entityList.add(entity); 
    } 
} 

Ale problem jest ten kod jest pełna niekontrolowanych odlewów. Czy ktoś może pomóc w lepszym sposobie realizacji tego?

Dziękujemy

+2

byłoby bardziej odpowiednie dla '' entityMap' się Mapa , Lista > 'ponieważ wartości są nie' 'Lista są' Lista ' – newacct

+0

To nie jest odpowiedź na twoje pytanie, ale rozważ użycie Guava Multimap zamiast mapy . –

+0

Zaproponowałem API 'ClassToInstanceMultimap' w [tej odpowiedzi] (https://stackoverflow.com/a/45260466/113632), po typach" Multimap "i" ClassToInstanceMap "Guavy. – dimo414

Odpowiedz

6

Chodzi o to, co jest "niezaznaczone cast"?

Czasami odlewy są bezpieczne, niestety dowód jest poza możliwościami javaca, co ogranicza tylko analizę statyczną wyszczególnioną w specyfikacji. Ale programista jest mądrzejszy niż javac.

W tym przypadku argumentuję, że są to "sprawdzone rzuty" i bardzo właściwe jest powstrzymanie ostrzeżenia.

Zobacz 2 inne podobne przykłady:

Heterogeneous container to store genericly typed objects in Java

Typesafe forName class loading

1

Nie trzeba Obsada:

(List<T>) entityMap.get(clazz).

Kiedy mówisz

entityMap.get(clazz)

rzeczywiście mają List<Object> który jest na tyle dla swoich potrzeb.

To samo dla

entityList = new ArrayList<T>();

należy po prostu użyć entityList = new ArrayList<Object>();

Twoje bezpieczeństwo typ jest zapewniona poprzez deklaracji metody

<T> void addEntity(Class<T> clazz, T entity) { 

i wykorzystania mapą mając jako klucz Klasa.

więc kod powinien wyglądać następująco:

private <T> void addEntity(Class<T> clazz, T entity) { 
      List<Object> entityList = entityMap.get(clazz); 
      if(entityList == null) { 
       entityList = new ArrayList<Object>(); 
       entityMap.put(clazz, entityList); 
      } 
      entityList.add(entity); 
    } 
Powiązane problemy