2012-12-18 15 views
6

Jak bezpiecznie rzucić mapę na mapę haszującą?Bezpieczna obsada na mapie skrótu

chcę uniknąć wyjątkiem klasy oddanych

HashMap<String, String> hMap; 

public void setHashMap(Map map){ 
    hMap = (HashMap<String, String>) map; 
} 
+3

Dlaczego 'setHashMap()' wymaga 'mapy', gdy naprawdę potrzebuje' HashMap'? –

+0

Co masz na myśli mówiąc "bezpiecznie"? Co chcesz zrobić, gdy nie można go obsadzić? Czy sprawienie, by kopia była akceptowalna? – Thilo

+0

Zewnętrzna biblioteka, której używam jest zaimplementowana za pomocą hashmap zamiast zwykłego interfejsu ... :( – Stainedart

Odpowiedz

17

Jeśli chcesz dokonać (płytkie) skopiować:

HashMap<String, String> copy = new HashMap<String, String>(map); 

Jeśli chcesz to zrobić tylko wtedy, gdy nie jest już HashMap :

HashMap<String, String> hashMap = 
    (map instanceof HashMap) 
     ? (HashMap) map 
     : new HashMap<String, String>(map); 
0

można zrobić:

if (map instanceof HashMap) { 
    hMap = (HashMap<String, String>) map; 
} else { 
    //do whatever you want instead of throwing an exception 
} 

lub po prostu otaczaj rzut za pomocą try/catch i przechwyć wyjątek, gdy się to stanie.

+0

Zakładając Oczywiście, że 'map' nie jest' HashMap ', ponieważ jeśli tak jest, to po prostu sprawdzenie' instanceof HashMap' nie będzie działać. Dowolne wywołania takie jak 'String s = map.get (" foo ") 'rzuci' ClassCastException'. – Brian

0

Nie należy przesyłać do HashMap! Przesyłaj na mapę!
Jeśli naprawdę masz powód na swoje pytanie, musisz utworzyć nową HashMap w przypadku, gdy mapa nie jest instancją mapy.
Ale to zły pomysł.

2

Twoja funkcja powinna być taka, jak poniżej, aby uniknąć wyjątków, takich jak ClassCastException lub NullPointerException. Tutaj każdy obiekt Map zostanie przypisany do HashMap do twojego pola klasy.

public void setHashMap(Map<String, String> map) { 

    if (map != null && map instanceof HashMap<?, ?>) { 
     hMap = (HashMap<String, String>) map; 
    } else if (map != null) { 
     hMap.putAll(map); 
    } 
} 
0

Jeśli masz zamiar zawsze zakładać, że jest to HashMap<String, String>, dlaczego nie po prostu to zrobić?

HashMap<String, String> hMap; 

public void setHashMap(HashMap<String, String> map){ 
    hMap = map; 
} 

Jeśli chcesz coś bardziej ogólny, że ponosi Map:

public void setHashMap(Map<String, String> map){ 
    if (map != null) 
     hMap = new HashMap<String, String>(map); 
    else 
     hMap = new HashMap<String, String>(); 
} 

Nie wymaga odlewania. Twój przykład nie zawierał również typu zwrotu. Założę się, że chciałeś umieścić void.

2

Ogólnie rzecz biorąc, nie można typować adresu Map do HashMap bez ryzyka wystąpienia wyjątku rzucanego przez klasę. Jeśli Map jest TreeMap, wówczas rzutowanie (i musi) zawiedzie.

Możesz uniknąć wyjątku od, używając opcji sprawdzania typu przed rzutowaniem za pomocą instanceof, ale jeśli test mówi "nie jest HashMap", utknąłeś. Nie będziesz w stanie wykonać obsady.

Praktyczne rozwiązania są:

  • zadeklarować hMap jako nie MapHashMap,
  • skopiować Map wpisy na nowo utworzone HashMap lub
  • (fuj) utworzyć podklasę zwyczaj HashMap że opakowuje prawdziwą mapę.

(Żadne z tych podejść nie zadziała we wszystkich przypadkach ...ale nie mogę zrobić konkretną rekomendację bez więcej szczegółów co mapa stosuje.)


A gdy jesteś na to, może to być odpowiednie złożyć raport o błędzie z dostawcami problematyczny biblioteka. Zmuszenie użytkownika do użycia konkretnej implementacji mapy jest (na pierwszy rzut oka) złym pomysłem.