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?


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 . 😎


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

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.


7

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


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();
    }
  }

}

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.