Najlepszy sposób na stworzenie pustej mapy w Javie

117

Muszę stworzyć pustą mapę.

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

Problem polega na tym, że powyższy kod generuje takie ostrzeżenie: Bezpieczeństwo typów: Niezaznaczone rzutowanie z mapy do HashMap

Jaki jest najlepszy sposób na stworzenie tej pustej mapy?

JorgeO
źródło
Jaki jest twój zadeklarowany typ dla fileParameters?
jjnguy
Prawdopodobnie otrzymasz również ClassCastException.
Tom Hawtin - tackline
1
fileParameters powinna być mapą, a nie HashMap.
Steve Kuo

Odpowiedzi:

241

1) Jeśli mapa może być niezmienna:

Collections.emptyMap()

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

Będziesz musiał użyć tego ostatniego czasami, gdy kompilator nie może automatycznie określić, jaki rodzaj mapy jest potrzebny (nazywa się to wnioskiem o typie ). Na przykład rozważmy metodę zadeklarowaną w ten sposób:

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

Przekazując pustą mapę bezpośrednio do niej, musisz wyraźnie określić typ:

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

2) Jeśli musisz mieć możliwość modyfikowania mapy, to na przykład:

new HashMap<String, String>()

(jak wskazał tehblanx )


Dodatek : Jeśli Twój projekt wykorzystuje guawę , masz następujące alternatywy:

1) Niezmienna mapa:

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

To prawda, nie ma tu dużych korzyści w porównaniu z Collections.emptyMap(). Z Javadoc :

Ta mapa zachowuje się i działa podobnie jak Collections.emptyMap()i jest preferowana głównie ze względu na spójność i łatwość utrzymania Twojego kodu.

2) Mapa, którą możesz modyfikować:

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

Mapszawiera podobne metody fabryczne do tworzenia wystąpień innych typów map, takich jak TreeMaplub LinkedHashMap.


Aktualizacja (2018) : W Javie 9 lub nowszej najkrótszy kod do tworzenia niezmiennej pustej mapy to:

Map.of()

... używając nowych metod fabrycznych z JEP 269 . 😎

Jonik
źródło
W większości przypadków wnioskowanie o typie działa (np. Działa map = Collections.emptyMap ())
Sébastien RoccaSerra
Tak prawda. Zredagowałem odpowiedź, aby była trochę bardziej wyczerpująca.
Jonik
16

Collections.emptyMap ()

basszero
źródło
Problem polegał na tym, że tę mapę można zastosować tylko do obiektu mapy, a nie HashMap
JorgeO
7
Powinieneś (ogólnie) unikać deklarowania obiektów ich określonych typów i zamiast tego używać interfejsu (lub abstrakcyjnego rodzica). Staraj się unikać „HashMap <String, String> foo;” i użyj "Map <String, String> foo;" zamiast tego
TofuBeer
10

Jeśli potrzebujesz instancji HashMap, najlepszym sposobem jest:

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

Ponieważ Map jest interfejsem, musisz wybrać klasę, która go utworzy, jeśli chcesz utworzyć pustą instancję. HashMap wydaje się równie dobry jak każdy inny - więc po prostu go używaj.

AndreiM
źródło
7

Albo Collections.emptyMap(), albo jeśli wnioskowanie o typie nie działa w Twoim przypadku,
Collections.<String, String>emptyMap()

Peter Štibraný
źródło
2

Ponieważ w wielu przypadkach pusta mapa jest używana do projektowania null-safe, można skorzystać z nullToEmptymetody narzędziowej:

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 dla zestawów:

class SetUtils {

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

}

i listy:

class ListUtils {

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

}
Vitalii Fedorenko
źródło