Ma

Maps in Java

11 Übungen

Über Maps

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.

HashMap

Java hat eine Reihe verschiedener Map-Implementierungen. HashMap ist eine häufig verwendete.

// Make an instance
Map<String, Integer> fruitPrices = new HashMap<>();
Note

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

HashMap verwendet 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

Map.of und Map.copyOf

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.

Über GitHub bearbeiten Der Link öffnet sich in einem neuen Fenster oder Tab

Lerne Maps

Das Üben ist gesperrt

Schalte 1 weitere Übung frei, um Maps zu üben