Eine Map ist eine Datenstruktur zum Speichern von Schlüssel-Wert-Paaren. Sie ähnelt Wörterbüchern in anderen Programmiersprachen. Die Map-Schnittstelle definiert die Operationen, die du mit einer Map ausführen kannst.
Java hat eine Reihe verschiedener Map-Implementierungen. HashMap ist eine häufig verwendete.
// Make an instance
Map<String, Integer> fruitPrices = new HashMap<>();
Wenn du eine Map-Variable definierst, empfiehlt es sich, die Variable als Typ Map zu definieren statt als konkreten Typ, wie im obigen Beispiel.
Diese Vorgehensweise erleichtert es, die Map-Implementierung später zu ändern.
HashMap hat auch einen Kopierkonstruktor.
// Make a copy of a map
Map<String, Integer> copy = new HashMap<>(fruitPrices);
Füge Einträge mit put zur Map hinzu.
fruitPrices.put("apple", 100);
fruitPrices.put("pear", 80);
// => { "apple" => 100, "pear" => 80 }
Mit jedem Schlüssel kann nur ein Wert verknüpft werden.
Wenn du put mit demselben Schlüssel aufrufst, wird der Wert des Schlüssels aktualisiert.
fruitPrices.put("pear", 40);
// => { "apple" => 100, "pear" => 40 }
Verwende get, um den Wert für einen Schlüssel abzurufen.
fruitPrices.get("apple"); // => 100
Verwende containsKey, um zu prüfen, ob die Map einen bestimmten Schlüssel enthält.
fruitPrices.containsKey("apple"); // => true
fruitPrices.containsKey("orange"); // => false
Entferne Einträge mit remove.
fruitPrices.put("plum", 90); // Add plum to map
fruitPrices.remove("plum"); // Removes plum from map
Die Methode size gibt die Anzahl der Einträge zurück.
fruitPrices.size(); // Returns 2
Du kannst die Methoden keySet oder values verwenden, um die Schlüssel bzw. die Werte einer Map als Set oder Collection zu erhalten.
fruitPrices.keySet(); // Returns "apple" and "pear" in a set
fruitPrices.values(); // Returns 100 and 80, in a Collection
hashCode und equals
HashMaps verwenden die Methoden hashCode und equals des Objekts, um herauszufinden, wo die Werte für einen Schlüssel gespeichert und wie sie abgerufen werden. Aus diesem Grund ist es wichtig, dass sich ihre Rückgabewerte zwischen dem Speichern und dem Abrufen nicht ändern, sonst kann die HashMap den Wert möglicherweise nicht finden.
Angenommen, wir haben die folgende Klasse, die als Schlüssel für eine Map verwendet wird:
public class Stock {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public int hashCode() {
return Objects.hash(name);
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (Objects.equals(Stock.class, obj.getClass()) && obj instanceof Stock other) {
return Objects.equals(name, other.name);
}
return false;
}
}
Die Methoden hashCode und equals hängen vom Feld name ab, das über setName geändert werden kann.
Eine Änderung des hashCode kann überraschende Ergebnisse liefern:
Stock stock = new Stock();
stock.setName("Beanies");
Map<Stock, Integer> stockCount = new HashMap<>();
stockCount.put(stock, 80);
stockCount.get(stock); // Returns 80
Stock other = new Stock();
other.setName("Beanies");
stockCount.get(other); // Returns 80 because "other" and "stock" are equal
stock.setName("Choccies");
stockCount.get(stock); // Returns null because hashCode value has changed
stockCount.get(other); // Also returns null because "other" and "stock" are not equal
stock.setName("Beanies");
stockCount.get(stock); // HashCode restored, so returns 80 again
stockCount.get(other); // Also returns 80 again because "other" and "stock" are back to equal
Eine weitere übliche Möglichkeit, Maps zu erstellen, ist die Verwendung von Map.of oder Map.ofEntries.
// Using Map.of
Map<String, Integer> temperatures = Map.of("Mon", 30, "Tue", 28, "Wed", 32);
// or using Map.ofEntries
Map<String, Integer> temperatures2 = Map.ofEntries(
Map.entry("Mon", 30),
Map.entry("Tue", 28),
Map.entry("Wed", 32)
);
Anders als HashMap befüllen sie die Map im Voraus und sind nach der Erstellung schreibgeschützt.
Map.copyOf erstellt eine schreibgeschützte Kopie einer Map.
Map<String, Integer> readOnlyFruitPrices = Map.copyOf(fruitPrices);
Der Aufruf von Methoden wie put, remove oder clear führt zu einer UnsupportedOperationException.