3898 Stimmen

Wie kann ich effizient über jeden Eintrag in einer Java Map iterieren?

Wenn ich ein Objekt habe, das die Map Schnittstelle in Java und ich möchte über jedes darin enthaltene Paar iterieren. Wie kann ich die Karte am effizientesten durchlaufen?

Hängt die Reihenfolge der Elemente von der spezifischen Kartenimplementierung ab, die ich für die Schnittstelle habe?

46 Stimmen

In Java 8 mit Lambda-Ausdruck: stackoverflow.com/a/25616206/1503859

5 Stimmen

57voto

Taras Melnyk Punkte 2711

Mit Java 8 können Sie Map mit forEach und Lambda-Ausdruck iterieren,

map.forEach((k, v) -> System.out.println((k + ":" + v)));

45voto

Donald Raab Punkte 6053

Mit Eclipse-Kollektionen würden Sie die forEachKeyValue Methode auf der MapIterable Schnittstelle, die von der MutableMap y ImmutableMap Schnittstellen und ihre Implementierungen.

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);

Wenn Sie eine anonyme innere Klasse verwenden, können Sie den Code wie folgt schreiben:

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);

Nota: Ich bin ein Committer für Eclipse Collections.

43voto

akhil_mittal Punkte 20953

Java 8

Wir haben forEach Methode, die eine Lambda-Ausdruck . Wir haben auch 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));

Iterieren Sie über Einträge (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 ist, dass sie leicht parallelisiert werden können, falls wir das wollen. Wir müssen einfach Folgendes verwenden parallelStream() anstelle von stream() oben.

forEachOrdered gegen forEach mit Strömen ? Die forEach folgt nicht der Begegnungsreihenfolge (sofern definiert) und ist von Natur aus nicht-deterministisch, während die forEachOrdered tut. Also forEach garantiert nicht, dass der Auftrag ausgeführt wird. Auch prüfen este für mehr.

41voto

Leigh Caldwell Punkte 9608

Theoretisch hängt der effizienteste Weg von der Implementierung von Map ab. Der offizielle Weg, dies zu tun, ist der Aufruf von map.entrySet() die eine Menge von Map.Entry , die jeweils einen Schlüssel und einen Wert enthalten ( entry.getKey() y entry.getValue() ).

In einer idiosynkratischen Implementierung könnte es einen Unterschied machen, ob Sie map.keySet() , map.entrySet() oder etwas anderes. Aber mir fällt kein Grund ein, warum jemand das so schreiben sollte. Wahrscheinlich macht es für die Leistung keinen Unterschied, was Sie tun.

Und ja, die Reihenfolge hängt von der Implementierung ab - ebenso wie (möglicherweise) die Reihenfolge der Einfügung und andere schwer zu kontrollierende Faktoren.

[Bearbeiten] Ich schrieb valueSet() ursprünglich aber natürlich entrySet() ist tatsächlich die Antwort.

39voto

Nitin Mahesh Punkte 3592

Lambda Ausdrucksweise Java 8

In Java 1.8 (Java 8) ist dies viel einfacher geworden, indem man forEach Methode von Aggregate operations( Stream-Operationen ), die ähnlich aussehen wie die Iteratoren von Iterierbar Schnittstelle.

Kopieren Sie einfach die folgende Anweisung in Ihren Code und benennen Sie die HashMap variabel von hm an Ihre HashMap-Variable, um ein Schlüssel-Wert-Paar auszugeben.

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.

Im Folgenden finden Sie den Beispielcode, den ich verwendet habe Lambda-Ausdruck . Dieses Zeug ist so cool. Muss man probieren.

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

Man kann auch verwenden Spliterator für dasselbe.

Spliterator sit = hm.entrySet().spliterator();

UPDATE


Einschließlich Dokumentationslinks zu Oracle Docs. Für mehr über Lambda Hier geht's weiter enlace und muss lesen Aggregierte Operationen und für Spliterator gehen Sie zu diesem enlace .

CodeJaeger.com

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.

Powered by:

X