2009-03-11 15 views
73

Potrzebuję utworzyć pustą mapę.Najlepszy sposób na utworzenie pustej mapy w Javie

if (fileParameters == null) 
    fileParameters = (HashMap<String, String>) Collections.EMPTY_MAP; 

Problem polega na tym, że powyższy kod generuje to ostrzeżenie: Typ bezpieczeństwa: Nieograniczony odlana z mapą do HashMap

co jest najlepszym sposobem, aby stworzyć tę pustą mapę?

+0

Jaki jest twój zadeklarowany typ dla fileParameters? – jjnguy

+0

Prawdopodobnie uzyskasz również wyjątek ClassCastException. –

+1

fileParameters powinna być Mapą, a nie HashMap. –

Odpowiedz

143

1) Jeżeli mapa może być niezmienna:

Collections.emptyMap(); 

// or, in some cases: 
Collections.<String, String>emptyMap(); 

You Będą musieli używać tego ostatniego czasami, gdy kompilator nie będzie w stanie automatycznie określić, jaki rodzaj mapy jest potrzebny (nazywa się to type inference). Na przykład, rozważmy metody zadeklarowane tak:

public void foobar(Map<String, String> map){ ... } 

Po minięciu pusty Mapa bezpośrednio do niego, trzeba być jawne o typie:

foobar(Collections.emptyMap());     // doesn't compile 
foobar(Collections.<String, String>emptyMap()); // works fine 

2) Jeśli trzeba można modyfikować z mapy, na przykład:

new HashMap<String, String>(); 

(jak tehblanx pointed out)


Uzupełnienie: jeśli projekt wykorzystuje Guava, dostępne są następujące warianty:

1) Niezmienne mapy:

ImmutableMap.of(); 
// or: 
ImmutableMap.<String, String>of(); 

prawda, żadne wielkie korzyści tutaj w porównaniu do Collections.emptyMap(). From the Javadoc:

Ta mapa zachowuje się i działa porównywalnie do Collections.emptyMap(), i jest korzystne głównie dla spójności i konserwacji swojego kodu .

2) mapy, które można modyfikować:

Maps.newHashMap(); 
// or: 
Maps.<String, String>newHashMap(); 

Maps zawiera podobne metody fabryczne instancji inne rodzaje map, jak również, takie jak TreeMap lub LinkedHashMap.

+0

W większości przypadków, pracuj nad wnioskami (np. map = Collections.emptyMap() działa) –

+0

Tak, to prawda. Zmieniłem odpowiedź na nieco bardziej wyczerpującą. – Jonik

9

Jeśli potrzebujesz instancję HashMap, najlepszym sposobem jest:

fileParameters = new HashMap<String,String>(); 

Od mapą jest interfejsem, trzeba wybrać pewną klasę, która tworzy wystąpienie go, jeśli chcesz utworzyć pusty instancji. HashMap wydaje się równie dobry jak każdy inny - więc po prostu go używaj.

13
+0

Problem polegał na tym, że ta mapa może być zastosowana tylko do obiektu Map, a nie do HashMap – JorgeO

+6

Powinieneś (ogólnie) unikać deklarowania obiektów należących do ich konkretnych typów i używać zamiast tego interfejsu (lub abstrakcyjnego elementu nadrzędnego). Staraj się unikać "HashMap foo;" i użyj "Map foo;" zamiast tego – TofuBeer

+0

+1 TofuBeer (jeśli tylko mógłbym) –

6

Albo Collections.emptyMap(), czy rodzaj wnioskowania nie działa w Twoim przypadku,
Collections.<String, String>emptyMap()

1

Ponieważ w wielu przypadkach pusta mapa służy do zerowej bezpieczny projektu, można wykorzystać metodę nullToEmpty użytkowy:

class MapUtils { 

    static <K,V> Map<K,V> nullToEmpty(Map<K,V> map) { 
    if (map != null) { 
     return map; 
    } else { 
     return Collections.<K,V>emptyMap(); // or guava ImmutableMap.of() 
    } 
    } 

} 

Podobnie do zestawów:

class SetUtils { 

    static <T> Set<T> nullToEmpty(Set<T> set) { 
    if (set != null) { 
     return set; 
    } else { 
     return Collections.<T>emptySet(); 
    } 
    } 

} 

oraz z list:

class ListUtils { 

    static <T> List<T> nullToEmpty(List<T> list) { 
    if (list != null) { 
     return list; 
    } else { 
     return Collections.<T>emptyList(); 
    } 
    } 

}