Der beste Weg, um eine leere Karte in Java zu erstellen

116

Ich muss eine leere Karte erstellen.

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

Das Problem ist, dass der obige Code diese Warnung erzeugt : Typensicherheit: Deaktivierte Umwandlung von Map in HashMap

Was ist der beste Weg, um diese leere Karte zu erstellen?

JorgeO
quelle
Was ist Ihr deklarierter Typ für fileParameters?
jjnguy
Sie werden wahrscheinlich auch eine ClassCastException erhalten.
Tom Hawtin - Tackline
1
fileParameters sollte eine Map und keine HashMap sein.
Steve Kuo

Antworten:

241

1) Wenn die Karte unveränderlich sein kann:

Collections.emptyMap()

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

Letzteres müssen Sie manchmal verwenden, wenn der Compiler nicht automatisch herausfinden kann, welche Art von Map benötigt wird (dies wird als Typinferenz bezeichnet ). Stellen Sie sich zum Beispiel eine Methode vor, die wie folgt deklariert ist:

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

Wenn Sie die leere Karte direkt an sie übergeben, müssen Sie den Typ explizit angeben:

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

2) Wenn Sie die Karte ändern müssen, dann zum Beispiel:

new HashMap<String, String>()

(wie Tehblanx betonte )


Nachtrag : Wenn Ihr Projekt Guava verwendet , haben Sie folgende Alternativen:

1) Unveränderliche Karte:

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

Zugegeben, keine großen Vorteile hier im Vergleich zu Collections.emptyMap(). Aus dem Javadoc :

Diese Zuordnung verhält sich vergleichbar und funktioniert vergleichbar mit Collections.emptyMap()und ist vor allem aus Gründen der Konsistenz und Wartbarkeit Ihres Codes vorzuziehen.

2) Karte, die Sie ändern können:

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

Mapsenthält ähnliche Factory-Methoden zum Instanziieren anderer Kartentypen, z. B. TreeMapoder LinkedHashMap.


Update (2018) : Unter Java 9 oder neuer lautet der kürzeste Code zum Erstellen einer unveränderlichen leeren Karte:

Map.of()

... mit den neuen Convenience Factory-Methoden von JEP 269 . 😎

Jonik
quelle
In den meisten Fällen funktioniert die Typinferenz (dh map = Collections.emptyMap () funktioniert)
Sébastien RoccaSerra
Ja stimmt. Ich habe die Antwort etwas umfassender bearbeitet.
Jonik
16

Collections.emptyMap ()

Basszero
quelle
Das Problem war, dass diese Karte nur auf ein Kartenobjekt angewendet werden kann, nicht auf eine HashMap
JorgeO
7
Sie sollten (im Allgemeinen) vermeiden, Objekte ihres spezifischen Typs zu deklarieren, und stattdessen die Schnittstelle (oder das abstrakte übergeordnete Element) verwenden. Vermeiden Sie "HashMap <String, String> foo;" und benutze "Map <String, String> foo;" stattdessen
TofuBeer
10

Wenn Sie eine Instanz von HashMap benötigen, ist der beste Weg:

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

Da Map eine Schnittstelle ist, müssen Sie eine Klasse auswählen, die sie instanziiert, wenn Sie eine leere Instanz erstellen möchten. HashMap scheint so gut wie jede andere zu sein - verwenden Sie das einfach.

AndreiM
quelle
7

Entweder Collections.emptyMap()oder wenn die Typinferenz in Ihrem Fall nicht funktioniert,
Collections.<String, String>emptyMap()

Peter Štibraný
quelle
2

Da in vielen Fällen eine leere Karte für das nullsichere Design verwendet wird, können Sie die nullToEmptyDienstprogrammmethode verwenden:

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

}  

Ähnliches gilt für Sets:

class SetUtils {

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

}

und Listen:

class ListUtils {

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

}
Vitalii Fedorenko
quelle