Was ist der beste Weg, um über die Elemente in einer HashMap
?
Also, wie zu tun Schleife durch 2 Karten gleichzeitig? mit der entrySet Methode? Ich habe es mit && versucht, aber es hat nicht funktioniert.
Was ist der beste Weg, um über die Elemente in einer HashMap
?
Wenn Sie nur an den Schlüsseln interessiert sind, können Sie durch die keySet()
der Karte:
Map<String, Object> map = ...;
for (String key : map.keySet()) {
// ...
}
Wenn Sie nur die Werte benötigen, verwenden Sie values()
:
for (Object value : map.values()) {
// ...
}
Wenn Sie schließlich sowohl den Schlüssel als auch den Wert benötigen, verwenden Sie entrySet()
:
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// ...
}
Eine Einschränkung: Wenn Sie Elemente mitten in der Iteration entfernen möchten, müssen Sie dies über einen Iterator tun (siehe karim79's Antwort ). Das Ändern von Positionswerten ist jedoch in Ordnung (siehe Map.Entry
).
Also, wie zu tun Schleife durch 2 Karten gleichzeitig? mit der entrySet Methode? Ich habe es mit && versucht, aber es hat nicht funktioniert.
Verwenden Sie zwei Iteratoren. Ein Beispiel für die Verwendung eines Iterators finden Sie in der akzeptierten Antwort.
Es ist nur effizienter, entrySet zu verwenden, wenn Sie sowohl Schlüssel als auch Werte benötigen. Wenn Sie nur das eine oder das andere benötigen, verwenden Sie nur das eine: stackoverflow.com/questions/3870064/
Iterieren Sie durch die entrySet()
etwa so:
public static void printMap(Map mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
System.out.println(pair.getKey() + " = " + pair.getValue());
it.remove(); // avoids a ConcurrentModificationException
}
}
Lesen Sie mehr über Map
.
Dies ist zwar veraltet, hilft aber, ConcurrentModificationExceptions gegenüber dem neuen foreach-Stil in den folgenden Antworten zu vermeiden. Sie können zum Beispiel über den separaten Iterator entfernen.
@karim79 was hältst du von der folgenden Möglichkeit: Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue()); }
Durch den Aufruf von "it.remove();" leeren Sie die Karte, so dass sie nicht wiederverwendet werden kann, wenn diese Karte eine Klassenvariable war. Haben Sie eine Lösung für dieses Problem?
Auszug aus der Referenz Wie man in Java über eine Karte iteriert :
Es gibt mehrere Möglichkeiten der Iteration über eine Map
in Java. Gehen wir die gebräuchlichsten Methoden durch und betrachten wir ihre Vor- und Nachteile. Da alle Maps in Java die Map-Schnittstelle implementieren, funktionieren die folgenden Techniken für jede Map-Implementierung ( HashMap
, TreeMap
, LinkedHashMap
, Hashtable
, usw.)
Methode Nr. 1 : Iteration über Einträge mit einer For-Each-Schleife.
Dies ist die gängigste Methode und in den meisten Fällen vorzuziehen. Sie sollte verwendet werden, wenn Sie sowohl Map-Schlüssel als auch Werte in der Schleife benötigen.
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
Beachten Sie, dass die For-Each-Schleife erst in Java 5 eingeführt wurde, so dass diese Methode nur in neueren Versionen der Sprache funktioniert. Auch eine For-Each-Schleife wirft NullPointerException
wenn Sie versuchen, über eine Karte zu iterieren, die Null ist, also sollten Sie vor der Iteration immer auf Null-Referenzen prüfen.
Methode #2 : Iteration über Schlüssel oder Werte mit einer For-Each-Schleife.
Wenn Sie nur Schlüssel oder Werte aus der Map benötigen, können Sie über keySet oder values anstelle von entrySet iterieren.
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
// Iterating over keys only
for (Integer key : map.keySet()) {
System.out.println("Key = " + key);
}
// Iterating over values only
for (Integer value : map.values()) {
System.out.println("Value = " + value);
}
Diese Methode bietet einen leichten Leistungsvorteil gegenüber entrySet
Iteration (etwa 10 % schneller) und ist sauberer.
Methode Nr. 3 : Iterieren mit Iterator.
Verwendung von Generika:
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<Integer, Integer> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
Ohne Generika:
Map map = new HashMap();
Iterator entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
Integer key = (Integer)entry.getKey();
Integer value = (Integer)entry.getValue();
System.out.println("Key = " + key + ", Value = " + value);
}
Dieselbe Technik können Sie auch für die Iteration über keySet
oder Werte.
Diese Methode mag redundant erscheinen, hat aber ihre eigenen Vorteile. Zunächst einmal ist sie die einzige Möglichkeit, in älteren Java-Versionen über eine Karte zu iterieren. Die andere wichtige Eigenschaft ist, dass es die einzige Methode ist, die es Ihnen erlaubt, während der Iteration Einträge aus der Map zu entfernen, indem Sie iterator.remove()
. Wenn Sie versuchen, dies während der For-Each-Iteration zu tun, erhalten Sie "unvorhersehbare Ergebnisse" gemäß Javadoc .
Von der Leistung her ist diese Methode mit einer For-Each-Iteration gleichzusetzen.
Methode Nr. 4 : Iteration über Schlüssel und Suche nach Werten (ineffizient).
Map<Integer, Integer> map = new HashMap<Integer, Integer>();
for (Integer key : map.keySet()) {
Integer value = map.get(key);
System.out.println("Key = " + key + ", Value = " + value);
}
Dies mag wie eine sauberere Alternative zu Methode #1 aussehen, ist aber in der Praxis ziemlich langsam und ineffizient, da das Abrufen von Werten nach einem Schlüssel zeitaufwändig sein kann (diese Methode ist in verschiedenen Map-Implementierungen 20-200% langsamer als Methode #1). Wenn Sie FindBugs installiert haben, wird es dies erkennen und Sie vor ineffizienter Iteration warnen. Diese Methode sollte vermieden werden.
Schlussfolgerung:
Wenn Sie nur Schlüssel oder Werte aus der Map benötigen, verwenden Sie Methode Nr. 2. Wenn Sie mit einer älteren Java-Version (kleiner als 5) arbeiten oder planen, Einträge während der Iteration zu entfernen, müssen Sie Methode Nr. 3 verwenden. Ansonsten verwenden Sie Methode 1.
Fügen wir den kleinen Hinweis hinzu, dass im Falle von ConcurrentMap
s, Iteration auf keySet()
stürzt in der Regel ab (es gibt keine Garantie, dass die Werte für früher gesammelte Schlüssel existieren). Andererseits ist die Verwendung von Iteratoren oder Einträgen sicher (sie beziehen sich immer auf vorhandene Objekte).
@arvind Wie könnte Methode #4 jemals ineffizient sein? Per Definition ist der Aufruf von get()
ist immer O(1) für eine HashMap. Das ist die Definition einer HashMap und der Benutzer fragte nach einer HashMap. Ich verstehe nicht, warum dies so hoch gevotet wird. Wenn Sie auf den Link von jemand anderem verweisen, stellen Sie sicher, dass er für die gestellte Frage tatsächlich Sinn macht.
Sie können durch die Einträge in einer Map
in mehrfacher Hinsicht. Holen Sie sich jeden Schlüssel und Wert wie folgt:
Map<?,?> map = new HashMap<Object, Object>();
for(Entry<?, ?> e: map.entrySet()){
System.out.println("Key " + e.getKey());
System.out.println("Value " + e.getValue());
}
Oder Sie können die Liste der Schlüssel mit
Collection<?> keys = map.keySet();
for(Object key: keys){
System.out.println("Key " + key);
System.out.println("Value " + map.get(key));
}
Wenn Sie nur alle Werte abrufen wollen und sich nicht um die Schlüssel kümmern, können Sie verwenden:
Collection<?> values = map.values();
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
7 Stimmen
Ich muss die Schlüssel und Werte abrufen und sie zu einem mehrdimensionalen Array hinzufügen
8 Stimmen
In Java 8 mit Lambda-Ausdruck : stackoverflow.com/a/25616206/1503859