Wie iteriere ich effizient über jeden Eintrag in einer Java Map?
-
09-06-2019 - |
Frage
Wenn ich ein Objekt habe, das das implementiert Map
Schnittstelle in Java und ich möchte jedes darin enthaltene Paar durchlaufen. Wie kann ich die Karte am effizientesten durchgehen?
Hängt die Reihenfolge der Elemente von der spezifischen Kartenimplementierung ab, die ich für die Schnittstelle habe?
Lösung
Map<String, String> map = ...
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
Andere Tipps
Um die anderen Antworten zusammenzufassen und sie mit meinem Wissen zu kombinieren, habe ich 10 Hauptmethoden gefunden, dies zu tun (siehe unten).Außerdem habe ich einige Leistungstests geschrieben (siehe Ergebnisse unten).Wenn wir beispielsweise die Summe aller Schlüssel und Werte einer Karte ermitteln möchten, können wir schreiben:
Benutzen Iterator Und Karteneintrag
long i = 0; Iterator<Map.Entry<Integer, Integer>> it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Integer, Integer> pair = it.next(); i += pair.getKey() + pair.getValue(); }
Benutzen für jede Und Karteneintrag
long i = 0; for (Map.Entry<Integer, Integer> pair : map.entrySet()) { i += pair.getKey() + pair.getValue(); }
Benutzen für jede ab Java 8
final long[] i = {0}; map.forEach((k, v) -> i[0] += k + v);
Benutzen Schlüsselsatz Und für jede
long i = 0; for (Integer key : map.keySet()) { i += key + map.get(key); }
Benutzen Schlüsselsatz Und Iterator
long i = 0; Iterator<Integer> itr2 = map.keySet().iterator(); while (itr2.hasNext()) { Integer key = itr2.next(); i += key + map.get(key); }
Benutzen für Und Karteneintrag
long i = 0; for (Iterator<Map.Entry<Integer, Integer>> entries = map.entrySet().iterator(); entries.hasNext(); ) { Map.Entry<Integer, Integer> entry = entries.next(); i += entry.getKey() + entry.getValue(); }
Verwendung von Java 8 Stream-API
final long[] i = {0}; map.entrySet().stream().forEach(e -> i[0] += e.getKey() + e.getValue());
Verwendung von Java 8 API parallel streamen
final long[] i = {0}; map.entrySet().stream().parallel().forEach(e -> i[0] += e.getKey() + e.getValue());
Benutzen IterableMap von
Apache Collections
long i = 0; MapIterator<Integer, Integer> it = iterableMap.mapIterator(); while (it.hasNext()) { i += it.next() + it.getValue(); }
Benutzen MutableMap von Eclipse (CS)-Sammlungen
final long[] i = {0}; mutableMap.forEachKeyValue((key, value) -> { i[0] += key + value; });
Leistungstests (Modus = AverageTime, System = Windows 8.1 64-Bit, Intel i7-4790 3,60 GHz, 16 GB)
Für eine kleine Karte (100 Elemente) ist die Punktzahl 0,308 die beste
Benchmark Mode Cnt Score Error Units test3_UsingForEachAndJava8 avgt 10 0.308 ± 0.021 µs/op test10_UsingEclipseMap avgt 10 0.309 ± 0.009 µs/op test1_UsingWhileAndMapEntry avgt 10 0.380 ± 0.014 µs/op test6_UsingForAndIterator avgt 10 0.387 ± 0.016 µs/op test2_UsingForEachAndMapEntry avgt 10 0.391 ± 0.023 µs/op test7_UsingJava8StreamApi avgt 10 0.510 ± 0.014 µs/op test9_UsingApacheIterableMap avgt 10 0.524 ± 0.008 µs/op test4_UsingKeySetAndForEach avgt 10 0.816 ± 0.026 µs/op test5_UsingKeySetAndIterator avgt 10 0.863 ± 0.025 µs/op test8_UsingJava8StreamApiParallel avgt 10 5.552 ± 0.185 µs/op
Für eine Karte mit 10.000 Elementen ist die Punktzahl 37,606 die beste
Benchmark Mode Cnt Score Error Units test10_UsingEclipseMap avgt 10 37.606 ± 0.790 µs/op test3_UsingForEachAndJava8 avgt 10 50.368 ± 0.887 µs/op test6_UsingForAndIterator avgt 10 50.332 ± 0.507 µs/op test2_UsingForEachAndMapEntry avgt 10 51.406 ± 1.032 µs/op test1_UsingWhileAndMapEntry avgt 10 52.538 ± 2.431 µs/op test7_UsingJava8StreamApi avgt 10 54.464 ± 0.712 µs/op test4_UsingKeySetAndForEach avgt 10 79.016 ± 25.345 µs/op test5_UsingKeySetAndIterator avgt 10 91.105 ± 10.220 µs/op test8_UsingJava8StreamApiParallel avgt 10 112.511 ± 0.365 µs/op test9_UsingApacheIterableMap avgt 10 125.714 ± 1.935 µs/op
Für eine Karte mit 100.000 Elementen ist die Punktzahl 1184,767 die beste
Benchmark Mode Cnt Score Error Units test1_UsingWhileAndMapEntry avgt 10 1184.767 ± 332.968 µs/op test10_UsingEclipseMap avgt 10 1191.735 ± 304.273 µs/op test2_UsingForEachAndMapEntry avgt 10 1205.815 ± 366.043 µs/op test6_UsingForAndIterator avgt 10 1206.873 ± 367.272 µs/op test8_UsingJava8StreamApiParallel avgt 10 1485.895 ± 233.143 µs/op test5_UsingKeySetAndIterator avgt 10 1540.281 ± 357.497 µs/op test4_UsingKeySetAndForEach avgt 10 1593.342 ± 294.417 µs/op test3_UsingForEachAndJava8 avgt 10 1666.296 ± 126.443 µs/op test7_UsingJava8StreamApi avgt 10 1706.676 ± 436.867 µs/op test9_UsingApacheIterableMap avgt 10 3289.866 ± 1445.564 µs/op
Diagramme (Leistungstests abhängig von der Kartengröße)
Tabelle (Leistungstests abhängig von der Kartengröße)
100 600 1100 1600 2100
test10 0.333 1.631 2.752 5.937 8.024
test3 0.309 1.971 4.147 8.147 10.473
test6 0.372 2.190 4.470 8.322 10.531
test1 0.405 2.237 4.616 8.645 10.707
test2 0.376 2.267 4.809 8.403 10.910
test7 0.473 2.448 5.668 9.790 12.125
test9 0.565 2.830 5.952 13.220 16.965
test4 0.808 5.012 8.813 13.939 17.407
test5 0.810 5.104 8.533 14.064 17.422
test8 5.173 12.499 17.351 24.671 30.403
Alle Tests laufen GitHub.
In Java 8 können Sie dies mithilfe der neuen Lambdas-Funktionen sauber und schnell erledigen:
Map<String,String> map = new HashMap<>();
map.put("SomeKey", "SomeValue");
map.forEach( (k,v) -> [do something with key and value] );
// such as
map.forEach( (k,v) -> System.out.println("Key: " + k + ": Value: " + v));
Die Art von k
Und v
wird vom Compiler abgeleitet und muss nicht verwendet werden Map.Entry
mehr.
Kinderleicht!
Ja, die Reihenfolge hängt von der jeweiligen Map-Implementierung ab.
@ScArcher2 verfügt über die elegantere Java 1.5-Syntax.In 1.4 würde ich so etwas tun:
Iterator entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
Entry thisEntry = (Entry) entries.next();
Object key = thisEntry.getKey();
Object value = thisEntry.getValue();
// ...
}
Typischer Code zum Durchlaufen einer Karte ist:
Map<String,Thing> map = ...;
for (Map.Entry<String,Thing> entry : map.entrySet()) {
String key = entry.getKey();
Thing thing = entry.getValue();
...
}
HashMap
ist die kanonische Kartenimplementierung und gibt keine Garantien (oder obwohl sie die Reihenfolge nicht ändern sollte, wenn keine Mutationsoperation daran durchgeführt wird). SortedMap
gibt Einträge basierend auf der natürlichen Reihenfolge der Schlüssel zurück, oder a Comparator
, falls vorhanden. LinkedHashMap
gibt Einträge entweder in Einfügereihenfolge oder Zugriffsreihenfolge zurück, je nachdem, wie es erstellt wurde. EnumMap
gibt Einträge in natürlicher Reihenfolge der Schlüssel zurück.
(Aktualisieren:Ich denke, das stimmt nicht mehr.) Notiz, IdentityHashMap
entrySet
Iterator verfügt derzeit über eine eigenartige Implementierung, die dasselbe zurückgibt Map.Entry
Instanz für jedes Element in der entrySet
!Allerdings schreitet der Iterator jedes Mal voran, wenn ein neues Element erstellt wird Map.Entry
ist aktualisiert.
Beispiel für die Verwendung von Iteratoren und Generika:
Iterator<Map.Entry<String, String>> entries = myMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
String key = entry.getKey();
String value = entry.getValue();
// ...
}
Dies ist eine zweiteilige Frage:
So iterieren Sie über die Einträge einer Karte - @ScArcher2 hat antwortete das perfekt.
Wie ist die Reihenfolge der Iteration? - wenn Sie nur verwenden Map
, dann gibt es sie streng genommen Keine Bestellgarantie.Sie sollten sich also nicht wirklich auf die von einer Implementierung vorgegebene Reihenfolge verlassen.Allerdings ist die SortedMap
Schnittstelle erweitert Map
und bietet genau das, was Sie suchen – Implementierungen sorgen immer für eine konsistente Sortierreihenfolge.
NavigableMap
ist eine weitere nützliche Erweiterung - das ist ein SortedMap
mit zusätzlichen Methoden zum Suchen von Einträgen anhand ihrer geordneten Position im Schlüsselsatz.Dies kann also möglicherweise die Notwendigkeit einer Iteration von vornherein überflüssig machen – Sie können möglicherweise das Spezifische finden entry
Sie sind nach der Verwendung des higherEntry
, lowerEntry
, ceilingEntry
, oder floorEntry
Methoden.Der descendingMap
method gibt Ihnen sogar eine explizite Methode von Umkehren der Durchlaufreihenfolge.
Es gibt mehrere Möglichkeiten, über die Karte zu iterieren.
Hier ist ein Vergleich ihrer Leistungen für einen gemeinsamen, in der Karte gespeicherten Datensatz, indem eine Million Schlüsselwertpaare in der Karte gespeichert und über die Karte iteriert werden.
1) Verwendung entrySet()
in für jede Schleife
for (Map.Entry<String,Integer> entry : testMap.entrySet()) {
entry.getKey();
entry.getValue();
}
50 Millisekunden
2) Verwendung keySet()
in für jede Schleife
for (String key : testMap.keySet()) {
testMap.get(key);
}
76 Millisekunden
3) Verwendung entrySet()
und Iterator
Iterator<Map.Entry<String,Integer>> itr1 = testMap.entrySet().iterator();
while(itr1.hasNext()) {
Map.Entry<String,Integer> entry = itr1.next();
entry.getKey();
entry.getValue();
}
50 Millisekunden
4) Verwendung keySet()
und Iterator
Iterator itr2 = testMap.keySet().iterator();
while(itr2.hasNext()) {
String key = itr2.next();
testMap.get(key);
}
75 Millisekunden
Ich habe verwiesen this link
.
Der richtige Weg, dies zu tun, besteht darin, die akzeptierte Antwort zu verwenden, da diese am effizientesten ist.Ich finde, dass der folgende Code etwas sauberer aussieht.
for (String key: map.keySet()) {
System.out.println(key + "/" + map.get(key));
}
Zu Ihrer Information, Sie können es auch verwenden map.keySet()
Und map.values()
wenn Sie nur an Schlüsseln/Werten der Karte interessiert sind und nicht an den anderen.
Mit Eclipse-Sammlungen (früher GS-Sammlungen), würden Sie die forEachKeyValue-Methode für verwenden MapIterable Schnittstelle, die von den Schnittstellen MutableMap und ImmutableMap und ihren Implementierungen geerbt wird.
final MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue(new Procedure2<Integer, String>()
{
public void value(Integer key, String value)
{
result.add(key + value);
}
});
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);
Mit der Lambda-Syntax von Java 8 können Sie den Code wie folgt schreiben:
MutableBag<String> result = Bags.mutable.empty();
MutableMap<Integer, String> map = Maps.mutable.of(1, "One", 2, "Two", 3, "Three");
map.forEachKeyValue((key, value) -> result.add(key + value));
Assert.assertEquals(Bags.mutable.of("1One", "2Two", "3Three"), result);
Notiz: Ich bin Committer für Eclipse Collections.
Theoretisch hängt der effizienteste Weg von der Implementierung von Map ab.Der offizielle Weg, dies zu tun, ist ein Anruf map.entrySet()
, was eine Reihe von zurückgibt Map.Entry
, die jeweils einen Schlüssel und einen Wert enthalten (entry.getKey()
Und entry.getValue()
).
Bei einer eigenwilligen Implementierung kann es einen Unterschied machen, ob Sie verwenden map.keySet()
, map.entrySet()
oder etwas anderes.Aber ich kann mir keinen Grund vorstellen, warum jemand es so schreiben sollte.Höchstwahrscheinlich hat es keinen Einfluss auf die Leistung, was Sie tun.
Und ja, die Reihenfolge hängt von der Implementierung ab – sowie (möglicherweise) der Reihenfolge des Einfügens und anderen schwer kontrollierbaren Faktoren.
[Bearbeiten] Ich habe geschrieben valueSet()
ursprünglich, aber natürlich entrySet()
ist tatsächlich die Antwort.
Java 8:
Sie können Lambda-Ausdrücke verwenden:
myMap.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
});
Weitere Informationen finden Sie hier Das.
Versuchen Sie dies mit Java 1.4:
for( Iterator entries = myMap.entrySet().iterator(); entries.hasNext();){
Entry entry = (Entry) entries.next();
System.out.println(entry.getKey() + "/" + entry.getValue());
//...
}
Mit Java 8
map.forEach((k, v) -> System.out.println((k + ":" + v)));
Java 8
Wir haben forEach
Methode, die a akzeptiert Lambda-Ausdruck.Wir haben auch bekommen Strom APIs.Betrachten Sie eine Karte:
Map<String,String> sample = new HashMap<>();
sample.put("A","Apple");
sample.put("B", "Ball");
Über Schlüssel iterieren:
sample.keySet().forEach((k) -> System.out.println(k));
Über Werte iterieren:
sample.values().forEach((v) -> System.out.println(v));
Über Einträge iterieren (mit forEach und Streams):
sample.forEach((k,v) -> System.out.println(k + ":" + v));
sample.entrySet().stream().forEach((entry) -> {
Object currentKey = entry.getKey();
Object currentValue = entry.getValue();
System.out.println(currentKey + ":" + currentValue);
});
Der Vorteil von Streams besteht darin, dass sie bei Bedarf problemlos parallelisiert werden können.Wir müssen es einfach nutzen parallelStream()
anstelle von stream()
über.
forEachOrdered
vs forEach
mit Streams?Der forEach
folgt nicht der Begegnungsreihenfolge (falls definiert) und ist von Natur aus nicht deterministisch, während die forEachOrdered
tut.Also forEach
übernimmt keine Gewähr für die Einhaltung der Bestellung.Überprüfen Sie auch Das für mehr.
Lambda Ausdruck Java 8
In Java 1.8 (Java 8) ist dies durch die Verwendung viel einfacher geworden für jede Methode aus Aggregatoperationen(Stream-Operationen), das den Iteratoren von ähnelt Wiederholbar Schnittstelle.
Kopieren Sie einfach die folgende Anweisung, fügen Sie sie in Ihren Code ein und benennen Sie sie um HashMap variabel von Hm zu Ihrer HashMap-Variable, um das Schlüssel-Wert-Paar auszudrucken.
HashMap<Integer,Integer> hm = new HashMap<Integer, Integer>();
/*
* Logic to put the Key,Value pair in your HashMap hm
*/
// Print the key value pair in one line.
hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));
// Just copy and paste above line to your code.
Unten finden Sie den Beispielcode, den ich versucht habe Lambda-Ausdruck.Das Zeug ist so cool.Müssen versuchen.
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
Random rand = new Random(47);
int i = 0;
while(i < 5) {
i++;
int key = rand.nextInt(20);
int value = rand.nextInt(50);
System.out.println("Inserting key: " + key + " Value: " + value);
Integer imap = hm.put(key, value);
if( imap == null) {
System.out.println("Inserted");
} else {
System.out.println("Replaced with " + imap);
}
}
hm.forEach((k, v) -> System.out.println("key: " + k + " value:" + v));
Output:
Inserting key: 18 Value: 5
Inserted
Inserting key: 13 Value: 11
Inserted
Inserting key: 1 Value: 29
Inserted
Inserting key: 8 Value: 0
Inserted
Inserting key: 2 Value: 7
Inserted
key: 1 value:29
key: 18 value:5
key: 2 value:7
key: 8 value:0
key: 13 value:11
Kann man auch nutzen Spliterator für das Selbe.
Spliterator sit = hm.entrySet().spliterator();
AKTUALISIEREN
Einschließlich Dokumentationslinks zu Oracle Docs.Weitere Informationen dazu Lambda Gehe hierher Verknüpfung und muss lesen Aggregierte Operationen und für Spliterator gehen Sie zu diesem Verknüpfung.
In Map kann man iterieren keys
und/oder values
und/oder both (e.g., entrySet)
hängt davon ab, welches Interesse man hat_ Wie:
1.) Iterieren Sie durch die keys -> keySet()
der Karte:
Map<String, Object> map = ...;
for (String key : map.keySet()) {
//your Business logic...
}
2.) Iterieren Sie durch die values -> values()
der Karte:
for (Object value : map.values()) {
//your Business logic...
}
3.) Durchlaufen Sie die both -> entrySet()
der Karte:
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
//your Business logic...
}
Darüber hinaus gibt es drei verschiedene Möglichkeiten, eine HashMap zu durchlaufen.Sie sind wie folgt_
//1.
for (Map.Entry entry : hm.entrySet()) {
System.out.print("key,val: ");
System.out.println(entry.getKey() + "," + entry.getValue());
}
//2.
Iterator iter = hm.keySet().iterator();
while(iter.hasNext()) {
Integer key = (Integer)iter.next();
String val = (String)hm.get(key);
System.out.println("key,val: " + key + "," + val);
}
//3.
Iterator it = hm.entrySet().iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
Integer key = (Integer)entry.getKey();
String val = (String)entry.getValue();
System.out.println("key,val: " + key + "," + val);
}
Am kompaktesten mit Java 8:
map.entrySet().forEach(System.out::println);
public class abcd{
public static void main(String[] args)
{
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Integer key:testMap.keySet()) {
String value=testMap.get(key);
System.out.println(value);
}
}
}
ODER
public class abcd {
public static void main(String[] args)
{
Map<Integer, String> testMap = new HashMap<Integer, String>();
testMap.put(10, "a");
testMap.put(20, "b");
testMap.put(30, "c");
testMap.put(40, "d");
for (Entry<Integer, String> entry : testMap.entrySet()) {
Integer key=entry.getKey();
String value=entry.getValue();
}
}
}
Wenn Sie eine generische, untypisierte Karte haben, können Sie Folgendes verwenden:
Map map = new HashMap();
for (Map.Entry entry : ((Set<Map.Entry>) map.entrySet())) {
System.out.println(entry.getKey() + "/" + entry.getValue());
}
Iterator iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry element = (Map.Entry)it.next();
LOGGER.debug("Key: " + element.getKey());
LOGGER.debug("value: " + element.getValue());
}
Sie können es mit Generika tun:
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());
}
Verwenden Sie Java 8:
map.entrySet().forEach(entry -> System.out.println(entry.getValue()));
//Functional Oprations
Map<String, String> mapString = new HashMap<>();
mapString.entrySet().stream().map((entry) -> {
String mapKey = entry.getKey();
return entry;
}).forEach((entry) -> {
String mapValue = entry.getValue();
});
//Intrator
Map<String, String> mapString = new HashMap<>();
for (Iterator<Map.Entry<String, String>> it = mapString.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, String> entry = it.next();
String mapKey = entry.getKey();
String mapValue = entry.getValue();
}
//Simple for loop
Map<String, String> mapString = new HashMap<>();
for (Map.Entry<String, String> entry : mapString.entrySet()) {
String mapKey = entry.getKey();
String mapValue = entry.getValue();
}
Die Reihenfolge hängt immer von der spezifischen Kartenimplementierung ab.Mit Java 8 können Sie Folgendes verwenden:
map.forEach((k,v) -> { System.out.println(k + ":" + v); });
Oder:
map.entrySet().forEach((e) -> {
System.out.println(e.getKey() + " : " + e.getValue());
});
Das Ergebnis wird dasselbe sein (gleiche Reihenfolge).Das von der Karte unterstützte EntrySet, sodass Sie die gleiche Reihenfolge erhalten.Die zweite ist praktisch, da Sie damit Lambdas verwenden können, z. B.Wenn Sie nur Integer-Objekte drucken möchten, die größer als 5 sind:
map.entrySet()
.stream()
.filter(e-> e.getValue() > 5)
.forEach(System.out::println);
Der folgende Code zeigt die Iteration durch LinkedHashMap und normale HashMap (Beispiel).Sie werden einen Unterschied in der Reihenfolge sehen:
public class HMIteration {
public static void main(String[] args) {
Map<Object, Object> linkedHashMap = new LinkedHashMap<>();
Map<Object, Object> hashMap = new HashMap<>();
for (int i=10; i>=0; i--) {
linkedHashMap.put(i, i);
hashMap.put(i, i);
}
System.out.println("LinkedHashMap (1): ");
linkedHashMap.forEach((k,v) -> { System.out.print(k + " (#="+k.hashCode() + "):" + v + ", "); });
System.out.println("\nLinkedHashMap (2): ");
linkedHashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
System.out.println("\n\nHashMap (1): ");
hashMap.forEach((k,v) -> { System.out.print(k + " (#:"+k.hashCode() + "):" + v + ", "); });
System.out.println("\nHashMap (2): ");
hashMap.entrySet().forEach((e) -> {
System.out.print(e.getKey() + " : " + e.getValue() + ", ");
});
}
}
LinkedHashMap (1):
10 (#=10):10, 9 (#=9):9, 8 (#=8):8, 7 (#=7):7, 6 (#=6):6, 5 (#=5):5, 4 (#=4):4, 3 (#=3):3, 2 (#=2):2, 1 (#=1):1, 0 (#=0):0,
LinkedHashMap (2):
10 : 10, 9 : 9, 8 : 8, 7 : 7, 6 : 6, 5 : 5, 4 : 4, 3 : 3, 2 : 2, 1 : 1, 0 : 0,
HashMap (1):
0 (#:0):0, 1 (#:1):1, 2 (#:2):2, 3 (#:3):3, 4 (#:4):4, 5 (#:5):5, 6 (#:6):6, 7 (#:7):7, 8 (#:8):8, 9 (#:9):9, 10 (#:10):10,
HashMap (2):
0 : 0, 1 : 1, 2 : 2, 3 : 3, 4 : 4, 5 : 5, 6 : 6, 7 : 7, 8 : 8, 9 : 9, 10 : 10,
Eine effektive iterative Lösung über eine Map ist eine „for every“-Schleife von Java 5 bis Java 7.Hier ist es:
for (String key : phnMap.keySet()) {
System.out.println("Key: " + key + " Value: " + phnMap.get(key));
}
Ab Java 8 können Sie einen Lambda-Ausdruck verwenden, um über eine Map zu iterieren.Es handelt sich um ein erweitertes „forEach“
phnMap.forEach((k,v) -> System.out.println("Key: " + k + " Value: " + v));
Wenn Sie eine Bedingung für Lambda schreiben möchten, können Sie diese folgendermaßen schreiben:
phnMap.forEach((k,v)->{
System.out.println("Key: " + k + " Value: " + v);
if("abc".equals(k)){
System.out.println("Hello abc");
}
});
Ja, viele Leute waren sich einig, dass dies der beste Weg ist, über a zu iterieren Map
.
Aber es gibt Chancen zu werfen nullpointerexception
wenn die Karte ist null
.Vergessen Sie nicht zu setzen null
.einchecken.
|
|
- - - -
|
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
}
package com.test;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class Test {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("ram", "ayodhya");
map.put("krishan", "mathura");
map.put("shiv", "kailash");
System.out.println("********* Keys *********");
Set<String> keys = map.keySet();
for (String key : keys) {
System.out.println(key);
}
System.out.println("********* Values *********");
Collection<String> values = map.values();
for (String value : values) {
System.out.println(value);
}
System.out.println("***** Keys and Values (Using for each loop) *****");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("Key: " + entry.getKey() + "\t Value: "
+ entry.getValue());
}
System.out.println("***** Keys and Values (Using while loop) *****");
Iterator<Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = (Map.Entry<String, String>) entries
.next();
System.out.println("Key: " + entry.getKey() + "\t Value: "
+ entry.getValue());
}
System.out
.println("** Keys and Values (Using java 8 using lambdas )***");
map.forEach((k, v) -> System.out
.println("Key: " + k + "\t value: " + v));
}
}
Es gibt viele Möglichkeiten, dies zu tun.Im Folgenden finden Sie einige einfache Schritte:
Angenommen, Sie haben eine Karte wie:
Map<String, Integer> m = new HashMap<String, Integer>();
Dann können Sie wie folgt vorgehen, um über Kartenelemente zu iterieren.
// ********** Using an iterator ****************
Iterator<Entry<String, Integer>> me = m.entrySet().iterator();
while(me.hasNext()){
Entry<String, Integer> pair = me.next();
System.out.println(pair.getKey() + ":" + pair.getValue());
}
// *********** Using foreach ************************
for(Entry<String, Integer> me : m.entrySet()){
System.out.println(me.getKey() + " : " + me.getValue());
}
// *********** Using keySet *****************************
for(String s : m.keySet()){
System.out.println(s + " : " + m.get(s));
}
// *********** Using keySet and iterator *****************
Iterator<String> me = m.keySet().iterator();
while(me.hasNext()){
String key = me.next();
System.out.println(key + " : " + m.get(key));
}