2010-07-01 15 views
7

En Python, puede tener pares de claves de valor en un diccionario donde se puede bucle a través de ellos, como se muestra a continuación:Loop Java HashMap like Python Dictionary?

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

¿Hay una manera de hacer esto con HashMaps Java?

Respuesta

20

Sí - por ejemplo:

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

Al comparar esto con la versión de Python, me recuerda por qué renuncié a Java hace años. –

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

Algo así ...

1

En Java, se puede hacer lo mismo como la siguiente.

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

¿Por qué el voto a favor? – bragboy

+0

No hice el downvote, pero este enfoque es menos eficiente que iterar sobre el entryset. El 'get()' tiene un costo adicional en cada iteración. Al menos no es la forma "correcta" de recorrer un mapa. Me imagino que uno votó negativamente por eso, cuán bueno es tu intención también. – BalusC

+2

@BalusC - sí, pero la creación del iterador MapEntrySet es (más probable) más costosa que la creación de un iterador de conjunto ... Dudo que sea un problema de rendimiento, e incluso si este fuera menos eficiente, nunca lo haría ** ** intente solucionar problemas de rendimiento * optimizando * para bucles como este. (+1 de mí, por cierto). –

6

Como se muestra en las respuestas, hay básicamente dos maneras de repetir un Map (vamos a suponer Map<String, String> en estos ejemplos).

  1. iterar sobre Map#entrySet():

    for (Entry<String, String> entry : map.entrySet()) { 
        System.out.println(entry.getKey() + "=" + entry.getValue()); 
    } 
    
  2. iterar sobre Map#keySet() y luego usar Map#get() para obtener el valor para cada clave:

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

La segunda es tal vez más legible, pero tiene un costo de rendimiento de llamadas innecesarias get() en cada iteración. Uno puede argumentar que la creación del iterador del conjunto de claves es menos costoso porque no necesita tener en cuenta los valores. Pero créalo o no, el keySet().iterator() crea y usa el mismo iterador como entrySet().iterator(). La única diferencia es que en el caso de keySet(), la llamada next() del iterador devuelve it.next().getKey() en lugar de it.next().

El AbstractMap#keySet()'s javadoc demuestra:

método iterador de la subclase devuelve un "objeto envoltorio" sobre este mapa de entrySet() iterador.

El código fuente AbstractMap también lo demuestra. He aquí un extracto de keySet() método (en algún lugar alrededor de la línea 300 en 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(); 
     } 
    }; 
} 

Tenga en cuenta que la lectura se prefiere en la optimización prematura, pero es importante tener esto en cuenta.