Vraag Itereren via een HashMap [dupliceren]


Mogelijke duplicaten: 
Hoe efficiënt te herhalen over elk item in een 'kaart'?

Wat is de beste manier om de items in a te herhalen? HashMap?


2827
2018-06-30 23:24


oorsprong


antwoorden:


Herhaal door de entrySet() zoals zo:

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
    }
}

Lees meer over Map.


2835
2018-06-30 23:27



Als u alleen geïnteresseerd bent in de sleutels, kunt u doorgaan met de keySet() van de kaart:

Map<String, Object> map = ...;

for (String key : map.keySet()) {
    // ...
}

Gebruik als u alleen de waarden nodig hebt values():

for (Object value : map.values()) {
    // ...
}

Tot slot, gebruik als u zowel de sleutel als de waarde wilt entrySet():

for (Map.Entry<String, Object> entry : map.entrySet()) {
    String key = entry.getKey();
    Object value = entry.getValue();
    // ...
}

Een waarschuwing: als u items in de middelste iteratie wilt verwijderen, moet u dit doen via een Iterator (zie karim79's antwoord). Het wijzigen van artikelwaarden is OK (zie Map.Entry).


4119
2018-06-30 23:28



Gehaald van de referentie Hoe te over een kaart in Java te versoepelen:

Er zijn verschillende manieren om over een iteratie te doen Map in Java. Laten we de meest gebruikelijke methoden bespreken en hun voor- en nadelen bekijken. Aangezien alle kaarten in Java de interface voor kaarten implementeren, werken de volgende technieken voor elke kaartimplementatie (HashMap, TreeMap, LinkedHashMap, Hashtable, enz.)

Methode # 1: Itering over items met behulp van een For-Each-lus.

Dit is de meest gebruikelijke methode en verdient in de meeste gevallen de voorkeur. Het moet worden gebruikt als u zowel kaartsleutels als waarden in de lus nodig hebt.

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

Merk op dat de For-Each-lus werd geïntroduceerd in Java 5, dus deze methode werkt alleen in nieuwere versies van de taal. Er zal ook een For-Each-lus worden gegooid NullPointerException als u probeert een kaart opnieuw te doorlopen die null is, dus voordat u itereert, moet u altijd controleren op nulverwijzingen.

Methode # 2: Itereren over toetsen of waarden met behulp van een For-Each-lus.

Als u alleen sleutels of waarden van de kaart nodig hebt, kunt u de sleutelreeks of waarden herhalen in plaats van entrySet.

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

Deze methode levert een klein prestatievoordeel op entrySet iteratie (ongeveer 10% sneller) en is meer schoon.

Methode # 3: Itereren met Iterator.

Generics gebruiken:

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

Zonder Generics:

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

U kunt dezelfde techniek ook gebruiken om opnieuw te itereren keySet of waarden.

Deze methode lijkt overbodig, maar heeft zijn eigen voordelen. Allereerst is dit de enige manier om een ​​kaart in oudere versies van Java te herhalen. De andere belangrijke functie is dat dit de enige methode is waarmee u items uit de kaart tijdens iteratie kunt verwijderen door te bellen iterator.remove(). Als je dit probeert te doen tijdens For-Each-iteratie, krijg je volgens '' onvoorspelbare resultaten '' javadoc.

Vanuit het oogpunt van prestaties is deze methode gelijk aan een For-Each-iteratie.

Methode # 4: Itereren over toetsen en zoeken naar waarden (inefficiënt).

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

Dit lijkt misschien een schoner alternatief voor methode # 1, maar in de praktijk is het vrij langzaam en inefficiënt omdat het ophalen van waarden door een sleutel tijdrovend kan zijn (deze methode in verschillende kaartimplementaties is 20% -200% langzamer dan methode # 1) ). Als u FindBugs hebt geïnstalleerd, zal het dit detecteren en u waarschuwen voor inefficiënte iteratie. Deze methode moet worden vermeden.

Conclusie:

Als u alleen sleutels of waarden van de kaart nodig heeft, gebruikt u methode # 2. Als u vastzit met een oudere versie van Java (minder dan 5) of van plan bent items tijdens iteratie te verwijderen, moet u methode # 3 gebruiken. Gebruik anders methode # 1.


739
2017-12-08 14:19



U kunt de vermeldingen in a herhalen Map op verschillende manieren. Krijg elke sleutel en waarde als volgt:

Map<?,?> map = new HashMap<Object, Object>();
for(Entry<?, ?> e: map.entrySet()){
    System.out.println("Key " + e.getKey());
    System.out.println("Value " + e.getValue());
}

Of u kunt de lijst met sleutels ophalen

Collection<?> keys = map.keySet();
for(Object key: keys){
    System.out.println("Key " + key);
    System.out.println("Value " + map.get(key));
}

Als u alleen alle waarden wilt ontvangen en niet bezig bent met de toetsen, kunt u het volgende gebruiken:

Collection<?> values = map.values();

77
2018-06-30 23:43



for (Map.Entry<String, String> item : params.entrySet()) {
    String key = item.getKey();
    String value = item.getValue();
}

70
2017-07-23 01:28



slimmer:

for (String key : hashMap.keySet()) {
    System.out.println("Key: " + key + ", Value: " + map.get(key));
}

55
2017-08-11 10:01



Hangt er van af. Als je weet dat je zowel de sleutel als de waarde van elke invoer nodig hebt, ga dan door de entrySet. Als je alleen de waarden nodig hebt, dan is er de values() methode. En als u alleen de toetsen nodig heeft, gebruik dan keyset().

Een slechte oefening zou zijn om alle sleutels te doorlopen, en dan altijd binnen de lus map.get(key) om de waarde te krijgen. Als je dat doet, dan is de eerste optie die ik heb geschreven voor jou.


40
2018-06-30 23:29