JavaRush /Java-Blog /Random-DE /Die 9 häufigsten Fragen zur Karte in Java
Treefeed
Level 21

Die 9 häufigsten Fragen zur Karte in Java

Veröffentlicht in der Gruppe Random-DE
Denken Sie daran, dass es sich bei einer Map um strukturierte Daten handelt, die aus einer Reihe von Schlüssel-Wert-Paaren bestehen, und dass jeder Schlüssel nur einmal in einer einzelnen Map verwendet werden kann. Dieses Thema behandelt 9 grundlegende Fragen zur Verwendung von Map in Java und seinen implementierten Klassen. Der Einfachheit halber werde ich in den Beispielen Verallgemeinerungen verwenden . Daher werde ich einfach Map schreiben, ohne den Map-Bezeichner anzugeben. Sie können jedoch davon ausgehen, dass beide Werte von K und V vergleichbar sind, was bedeutet, dass K Comparable erweitert und V auch Comparable erweitert .Die 9 häufigsten Fragen zur Karte in Java – 1

0. Konvertieren einer Karte in eine Liste

In Java bietet die Map- Schnittstelle drei Arten von Sammlungen: einen Schlüsselsatz, einen Wertesatz und einen Schlüsselwertsatz. Alle können mithilfe des Konstruktors oder der Methode in eine ListeaddAll() umgewandelt werden . Der folgende Codeausschnitt zeigt, wie man aus einer Map eine ArrayList erstellt .
// Liste der Schlüssel
List keyList = new ArrayList(Map.keySet());
//Liste von Werten
List valueList = new ArrayList(Map.valueSet());
//Schlüsselwert auflisten
List entryList = new ArrayList(Map.entrySet());

1. Durchlaufen Sie alle Werte in der Karte

Das Durchgehen jedes Schlüssel-Wert-Paares ist das grundlegendste Verfahren zum Durchgehen einer Karte. In Java wird jedes Paar in einem Map-Feld namens Map.Entry gespeichert . Map.entrySet()gibt eine Reihe von Schlüsselwerten zurück. Der effizienteste Weg, alle Werte einer Map zu durchlaufen, wäre also:
for(Entry entry: Map.entrySet()) {
  //hol den Schlüssel
  K key = entry.getKey();
  //Wert erhalten
  V value = entry.getValue();
}
Wir können auch verwenden Iterator, insbesondere in Versionen, die jünger als JDK 1.5 sind
Iterator itr = Map.entrySet().iterator();
while(itr.hasNext()) {
  Entry entry = itr.next();
  //hol den Schlüssel
  K key = entry.getKey();
  //Wert erhalten
  V value = entry.getValue();
}

2. Ordnen der Karte nach Schlüsseln

Das Organisieren von Karten nach Schlüsseln ist ein weiteres häufig verwendetes Verfahren. Die erste Möglichkeit besteht darin, Map.Entry zur Liste hinzuzufügen und mit einem Komparator zu sortieren, der nach Werten sortiert.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getKey().compareTo(e2.getKey());
  }
});
Eine andere Möglichkeit: Verwenden Sie SortedMap , das zusätzlich auch seine Schlüssel in der richtigen Reihenfolge anordnet. Alle Schlüssel müssen jedoch Comparable verkörpern oder vom Komparator akzeptiert werden. Eine der implementierten Klassen SortedMapist TreeMap . Sein Konstruktor akzeptiert einen Komparator. Der folgende Code zeigt, wie man einen normalen Mapin einen geordneten umwandelt.
SortedMap sortedMap = new TreeMap(new Comparator() {

  @Override
  public int compare(K k1, K k2) {
    return k1.compareTo(k2);
  }

});
sortedMap.putAll(Map);

3. Ordnen Sie die Karte nach Werten

Das Hinzufügen einer Karte zur Liste und das anschließende Sortieren funktioniert in diesem Fall, aber dieses Mal müssen Sie verwenden Entry.getValue(). Der folgende Code ist fast derselbe wie zuvor.
List list = new ArrayList(Map.entrySet());
Collections.sort(list, new Comparator() {

  @Override
  public int compare(Entry e1, Entry e2) {
    return e1.getValue().compareTo(e2.getValue());
  }

});
SortedMapWir können es in diesem Fall immer noch verwenden , aber nur, wenn die Werte eindeutig sind. In diesem Fall können Sie das Schlüssel-Wert-Paar in einen Schlüsselwert umwandeln. Diese Lösung weist erhebliche Einschränkungen auf und wird von mir nicht empfohlen.

4. Initialisieren einer statischen/unveränderlichen Karte

Wenn Sie möchten, dass eine Map unveränderlich bleibt, ist es eine gute Möglichkeit, sie in eine unveränderliche Map zu kopieren. Mit dieser defensiven Programmiertechnik können Sie eine Map erstellen, die nicht nur sicher zu verwenden, sondern auch threadsicher ist. Um eine statische/unveränderliche Map zu initialisieren, können wir einen Initialisierer verwenden static(siehe unten). Das Problem mit diesem Code besteht darin, dass Map zwar als deklariert ist static final, wir aber beispielsweise nach der Initialisierung weiterhin damit arbeiten können Test.Map.put(3,"three");. Es handelt sich also nicht um echte Unveränderlichkeit. Um eine unveränderliche Map mit einem statischen Initialisierer zu erstellen, benötigen wir eine superanonyme Klasse, die wir im letzten Initialisierungsschritt zur unveränderlichen Map hinzufügen. Bitte schauen Sie sich den zweiten Teil des Codes an. Wenn eine UnsupportedOperationException ausgelöst wird , wenn Sie ausführen Test.Map.put(3,"three");.
public class Test {

  private static final Map Map;
  static {
    Map = new HashMap();
    Map.put(1, "one");
    Map.put(2, "two");
  }
}
public class Test {

  private static final Map Map;
  static {
    Map aMap = new HashMap();
    aMap.put(1, "one");
    aMap.put(2, "two");
    Map = Collections.unmodifiableMap(aMap);
  }
}
Die Guava- Bibliothek unterstützt auch verschiedene Möglichkeiten zum Initialisieren statischer und unveränderlicher Sammlungen. Weitere Informationen zu den Vorteilen des Dienstprogramms für unveränderliche Sammlungen von Guava finden Sie im Abschnitt „Unveränderliche Sammlungen“ im Guava-How-to .

5. Unterschied zwischen HashMap, TreeMap und Hashtable

Es gibt drei Hauptimplementierungen der Map- Schnittstelle in Java: HashMap , TreeMap und Hashtable . Die Hauptunterschiede sind wie folgt:
  • Reihenfolge der Passage . HashMap und HashTable garantieren nicht die Reihenfolge der Map; Sie übernehmen insbesondere keine Gewähr dafür, dass die Bestellung im Laufe der Zeit gleich bleibt. Aber TreeMapes ordnet alle Werte in der „natürlichen Reihenfolge“ der Schlüssel oder durch einen Komparator.
  • Gültige Schlüssel-Wert-Paare. HashMapermöglicht es Ihnen, einen Nullschlüssel und einen Nullwert zu haben. HashTableerlaubt keinen Nullschlüssel oder Nullwert. Wenn TreeMapdie natürliche Reihenfolge verwendet wird oder der Komparator keinen Nullschlüssel zulässt, wird eine Ausnahme ausgelöst.
  • Synchronisierung . Nur HashTablesynchronisiert, der Rest nicht. Wenn jedoch keine Thread-sichere Implementierung erforderlich ist, wird empfohlen, HashMapstattdessen „ zu verwenden HashTable.
Detaillierterer Vergleich
.                       | HashMap | HashTable | TreeMap
-------------------------------------------------------

Упорядочивание          |нет      |нет        | да
null в ключ-Bedeutung    | да-да   | нет-нет   | нет-да
синхронизировано        | нет     | да        | нет
производительность      | O(1)    | O(1)      | O(log n)
воплощение              | корзины | корзины   | красно-чёрное дерево
Lesen Sie mehr über die Beziehung zwischen HashMap und HashMap . TreeMap vs. Hashtable vs. LinkedHashMap .

6. Karte mit umgekehrter Suche/Ansicht

Manchmal benötigen wir eine Reihe von Schlüssel-Schlüssel-Paaren, was bedeutet, dass die Werte genauso einzigartig sind wie die Schlüssel (ein Eins-zu-Eins-Muster). Diese Konsistenz ermöglicht es Ihnen, eine „invertierte Ansicht/Suche“ auf der Karte zu erstellen. Das heißt, wir können einen Schlüssel anhand seines Werts finden. Diese Datenstruktur wird als bidirektionale Map bezeichnet , was vom JDK leider nicht unterstützt wird. Sowohl Apache Common Collections als auch Guava bieten bidirektionale Kartenimplementierungen namens BidiMap bzw. BiMap. Beide führen eine Einschränkung ein, die eine 1:1-Zuordnung zwischen Schlüsseln und Werten erzwingt.

7. Flache Kopie der Karte

Fast alle, wenn nicht alle Maps in Java enthalten einen Kopierkonstruktor für eine andere Map. Der Kopiervorgang ist jedoch nicht synchronisiert. Das heißt, wenn ein Thread eine Map kopiert, kann ein anderer Thread ihre Struktur ändern. Um eine plötzliche Desynchronisierung der Kopie zu verhindern, sollte in einem solchen Fall einer von ihnen verwendet werden Collections.synchronizedMap().
Map copiedMap = Collections.synchronizedMap(Map);
Eine weitere interessante Möglichkeit zum flachen Kopieren ist die Verwendung von clone(). Aber es wird NICHT einmal vom Erfinder des Java-Collections-Frameworks, Joshua Bloch, empfohlen. In der Debatte „ Copy Constructor vs. Cloning “ vertritt er den Standpunkt: Zitat: „Ich stelle oft eine öffentliche Klonmethode in konkreten Klassen bereit, weil die Leute erwarten, dass sie dort vorhanden sind. ... es ist eine Schande, dass das Klonen kaputt ist, aber es.“ ist passiert. ... Klonen ist eine Schwachstelle und ich denke, die Menschen sollten vor seinen Grenzen gewarnt werden.“ Aus diesem Grund zeige ich Ihnen nicht einmal, wie Sie die Methode clone()zum Kopieren von Map verwenden

8. Erstellen Sie eine leere Karte

Wenn Mapunveränderlich, verwenden Sie:
Map = Collections.emptyMap();
Oder verwenden Sie eine andere Ausführungsform. Zum Beispiel:
Map = new HashMap();
ENDE
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION