2010-07-01 5 views
7

In Python können Sie Schlüssel, Wert-Paare in einem Wörterbuch, in dem Sie eine Schleife durch sie können, wie unten dargestellt:Schleife Java HashMap wie Python Dictionary?

for k,v in d.iteritems(): 
    print k,v 

Gibt es eine Möglichkeit, dies mit Java HashMaps zu tun?

Antwort

20

Ja - zum Beispiel:

Map<String, String> map = new HashMap<String, String>(); 
// add entries to the map here 

for (Map.Entry<String, String> entry : map.entrySet()) { 
    String k = entry.getKey(); 
    String v = entry.getValue(); 
    System.out.printf("%s %s\n", k, v); 
} 
+8

Der Vergleich mit der Python-Version erinnert mich daran, warum ich Java vor Jahren aufgegeben habe. –

3
Set<Map.Entry> set = d.entrySet(); 
for(Map.Entry i : set){ 
    System.out.println(i.getKey().toString() + i.getValue().toString); 
} 

So etwas ...

1

In Java können Sie das gleiche wie das folgende tun.

HashMap<String, String> h = new HashMap<String, String>(); 
    h.put("1","one"); 
    h.put("2","two"); 
    h.put("3","three"); 

    for(String key:h.keySet()){ 
     System.out.println("Key: "+ key + " Value: " + h.get(key)); 
    } 
+0

Warum der Downvote? – bragboy

+0

Ich habe den Downvote nicht gemacht, aber dieser Ansatz ist weniger effizient als das Iterieren über das Entryset. Das 'get()' hat bei jeder Iteration zusätzliche Kosten. Es ist zumindest nicht der "richtige" Weg, um eine Karte zu durchlaufen. Ich kann mir vorstellen, dass man deswegen abwertet, wie gut deine Absicht auch ist. – BalusC

+2

@BalusC - Ja, aber das Erstellen des MapEntrySet-Iterators ist (wahrscheinlich) teurer als das Erstellen eines Set-Iterators ... Ich bezweifle, dass es ein Performance-Problem ist, und selbst wenn dies weniger performant wäre, würde ich es niemals machen ** Versuchen Sie, Leistungsprobleme zu beheben, indem Sie * für solche Schleifen * optimieren. (+1 von mir, BTW). –

6

Wie in den Antworten gezeigt, gibt es grundsätzlich zwei Möglichkeiten, ein Map zu iterieren (die Map<String, String> in diesen Beispielen annehmen lassen).

  1. Iterate über Map#entrySet():

    for (Entry<String, String> entry : map.entrySet()) { 
        System.out.println(entry.getKey() + "=" + entry.getValue()); 
    } 
    
  2. Iterate über Map#keySet() und dann Map#get(), um den Wert für jeden Schlüssel zu erhalten:

    for (String key : map.keySet()) { 
        System.out.println(key + "=" + map.get(key)); 
    } 
    

Das zweite ist vielleicht mehr lesbar, aber es hat eine Performance-Kosten unnötigerweise zu nennen get() bei jeder Iteration. Ein Argument könnte sein, dass das Erstellen des Keyset-Iterators weniger teuer ist, da die Werte nicht berücksichtigt werden müssen. Aber glauben Sie es oder nicht, die keySet().iterator() erstellt und verwendet den gleichen Iterator als entrySet().iterator(). Der einzige Unterschied ist, dass im Fall der keySet() der next() Aufruf des Iterators it.next().getKey() statt it.next() zurückgibt.

Die AbstractMap#keySet()'s javadoc beweist dies:

Die Iteratormethode der Unterklasse gibt ein „Wrapper-Objekt“ über dies entrySet() Iterators Karte.

Der AbstractMap Quellcode beweist dies auch. Hier ist ein Auszug aus keySet() Methode (irgendwo um die Linie 300 in Java 1.6):

public Iterator<K> iterator() { 
    return new Iterator<K>() { 
     private Iterator<Entry<K,V>> i = entrySet().iterator(); // <----- 

     public boolean hasNext() { 
      return i.hasNext(); 
     } 

     public K next() { 
      return i.next().getKey(); // <----- 
     } 

     public void remove() { 
      i.remove(); 
     } 
    }; 
} 

Beachten Sie, dass die Lesbarkeit vorzeitige Optimierung bevorzugt über werden soll, aber es ist wichtig, dies im Auge zu haben.