2010-07-01 8 views
7

In Python, si può avere chiavi, coppie di valori in un dizionario in cui è possibile ciclo attraverso di loro, come illustrato di seguito:Loop Java HashMap come dizionario Python?

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

C'è un modo per fare questo con Java HashMaps?

risposta

20

Sì - per esempio:

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

Confrontando questo con la versione di Python mi viene in mente perché ho abbandonato Java anni fa. –

6

Il HashMap.entrySet() torneranno fagioli di coppie di valori chiave simili al dictionary.iteritems(). È quindi possibile eseguire il ciclo attraverso di loro.

Penso che sia la cosa più vicina alla versione Python.

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

Qualcosa del genere ...

1

In Java, si può fare lo stesso come il seguente.

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

Perché il downvote? – bragboy

+0

Non ho eseguito il downvote, ma questo approccio è meno efficiente di iterare su entryset. 'Get()' ha un costo aggiuntivo per ogni iterazione. Non è almeno il modo "giusto" per scorrere una mappa. Posso immaginare che un downvoted per questo, quanto sia buono il tuo intento. – BalusC

+2

@BalusC - sì, ma creare l'iteratore MapEntrySet è (molto probabilmente) più costoso, quindi creare un iteratore di set ... dubito che si tratti di un problema di prestazioni, e anche se questo fosse meno performante, non avrei mai ** prova a risolvere i problemi di prestazioni * ottimizzando * per cicli come questo. (+1 da me, BTW). –

6

Come mostrato nelle risposte, ci sono fondamentalmente due modi per iterare su una Map (supponiamo Map<String, String> in questi esempi).

  1. iterare Map#entrySet():

    for (Entry<String, String> entry : map.entrySet()) { 
        System.out.println(entry.getKey() + "=" + entry.getValue()); 
    } 
    
  2. iterare Map#keySet() e quindi utilizzare Map#get() per ottenere il valore per ogni tasto:

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

la seconda è forse più leggibile, ma ha un costo di prestazioni di chiamata inutilmente get() ad ogni iterazione. Si potrebbe argomentare che la creazione dell'iteratore di keyset è meno costosa in quanto non è necessario tenere conto dei valori. Ma ci crediate o no, lo keySet().iterator() crea e utilizza lo stesso iteratore come entrySet().iterator(). L'unica differenza è che nel caso dello keySet() la chiamata di iteratore next() restituisce it.next().getKey() anziché it.next().

Il AbstractMap#keySet()'s javadoc dimostra questo:

metodo iteratore del sottoclasse restituisce un "oggetto wrapper" over entrySet() iteratore di questa mappa.

Il codice sorgente AbstractMap lo dimostra. Ecco un estratto di keySet() metodo (da qualche parte attorno alla riga 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(); 
     } 
    }; 
} 

Si noti che la leggibilità dovrebbe essere preferito su ottimizzazione prematura, ma è importante avere questo in mente.