2010-11-20 15 views
347

que tienen este campo:¿Cómo cada uno de los hashmap?

HashMap<String, HashMap> selects = new HashMap<String, HashMap>(); 

Para cada Hash<String, HashMap> Necesito crear un ComboBox, cuyos elementos son el valor (que pasa a ser un HashMap en sí) de HashMap <String, **HashMap**>.

A modo de (no funcionamiento) la demostración:

for (int i=0; i < selects.size(); i++) { 
    HashMap h = selects[i].getValue(); 
    ComboBox cb = new ComboBox(); 

    for (int y=0; y < h.size(); i++) { 
     cb.items.add(h[y].getValue); 
    } 
} 
+3

En Java 8 usando Lambda: http://stackoverflow.com/a/25616206/1503859 –

Respuesta

856

Sé que soy un poco tarde para eso, pero voy a compartir lo que hice también, en caso de que ayuda a otra persona:

HashMap<String, HashMap> selects = new HashMap<String, HashMap>(); 

for(Map.Entry<String, HashMap> entry : selects.entrySet()) { 
    String key = entry.getKey(); 
    HashMap value = entry.getValue(); 

    // do what you have to do here 
    // In your case, another loop. 
} 
+40

Nunca recuerdo cómo escribir esto, así que siempre vuelvo a esta misma respuesta. Upvoted, porque esta es una respuesta limpia y este código está copiado en muchos lugares de mis proyectos, ¡gracias! – Katu

+1

@Katu simplemente escriba yourmap..entrySet(). For y el autocompletado IDE lo manejará. –

2
+0

icyrock.com, no funciona – Mediator

+1

Funciona definitivamente, lo uso todos los días :) ¿Qué exactamente no funciona? Como tiene 'HashMap ', necesitaría dos bucles, uno para el HashMap externo y otro para el HashMap interno. Por cierto, definitivamente deberías tipear el segundo HashMap, no sabes lo que almacenas en él, pero algo como HashMap > - aunque, en tu ejemplo, parece que debes usar 'HashMap > '. Y otra cosa: use interfaces: 'Map ' cuando pueda. –

43

Map.values():

HashMap<String, HashMap<SomeInnerKeyType, String>> selects = 
    new HashMap<String, HashMap<SomeInnerKeyType, String>>(); 

... 

for(HashMap<SomeInnerKeyType, String> h : selects.values()) 
{ 
    ComboBox cb = new ComboBox(); 
    for(String s : h.values()) 
    { 
     cb.items.add(s); 
    } 
} 
+1

+1: Este es un enfoque más ordenado que mi respuesta (asumiendo que estamos usando Java 5 o posterior) –

+0

El uso de argumentos genéricos en el HashMap externo parecería indicar Java 5 o posterior. [[Pero me pregunté sobre qué era Java, ya que el HashMap interno no tenía argumentos genéricos y había un acceso de matriz hecho en un HashMap ... pero es solo un código "pseudo" para transmitir la pregunta. ]] –

+0

Bert F, no trabajas – Mediator

13

Puede repetir un HashMap (otras y muchas colecciones) usando un iterador, por ejemplo:

HashMap<T,U> map = new HashMap<T,U>(); 

... 

Iterator it = map.values().iterator(); 

while (it.hasNext()) { 
    System.out.println(it.next()); 
} 
+1

No puedo con un diseño de este tipo por debajo del nivel – Mediator

+2

@ Sí, puede. Puede crear un iterador interno basado en 'it.next()'. –

12

general, hago lo mismo que cx42net, pero no crean explícitamente una entrada.

HashMap<String, HashMap> selects = new HashMap<String, HashMap>(); 
for (String key : selects.keySet()) 
{ 
    HashMap<innerKey, String> boxHolder = selects.get(key); 
    ComboBox cb = new ComboBox(); 
    for (InnerKey innerKey : boxHolder.keySet()) 
    { 
     cb.items.add(boxHolder.get(innerKey)); 
    } 
} 

Esto sólo parece el más intuitivo para mí, creo que tengo prejuicios contra iterar sobre los valores de un mapa.

153

Lambda Expresión de Java 8

En Java 1.8 (Java 8) se ha convertido en mucho más fácil mediante el uso de forEach método de las operaciones de agregados (operaciones Stream) que se parece a iteradores desde Iterable Interfaz.

Sólo copiar y pegar debajo de declaración a su código y cambiar el nombre de la variable deHashMap de hm a la variable de HashMap para imprimir par clave-valor.

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

Aquí se muestra un ejemplo donde se utiliza una expresión Lambda:

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 

También se puede utilizar Spliterator para el mismo.

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

ACTUALIZACIÓN


La inclusión de enlaces a la documentación de Oracle Docs. Para obtener más información sobre Lambda vaya a este link y debe leer Aggregate Operations y para Spliterator vaya a este link.

+0

y supongo que no podemos variables locales dentro del alcance adjunto sin declararlos definitivos. El programa 'Variable local definida en un ámbito adjunto debe ser final o efectivamente final' mientras se usa la variable declarada fuera del cuerpo lambda, a diferencia de los cierres en groovy. – Mahesha999

+2

La desventaja de usar lambdas es que no puedes devolver el otro método, mientras estás dentro de la lambda. – apscience

5

Como se mencionó anteriormente, en Java 8 tenemos el método forEach que acepta un lambda expression. Pero también tenemos stream API.

iterar sobre las entradas (usando forEach y arroyos):

sample.forEach((k,v) -> System.out.println(k + "=" + v)); 
sample.entrySet().stream().forEachOrdered((entry) -> { 
      Object currentKey = entry.getKey(); 
      Object currentValue = entry.getValue(); 
      System.out.println(currentKey + "=" + currentValue); 
     }); 
sample.entrySet().parallelStream().forEach((entry) -> { 
      Object currentKey = entry.getKey(); 
      Object currentValue = entry.getValue(); 
      System.out.println(currentKey + "=" + currentValue); 
     }); 

La ventaja de flujos es que pueden ser paralelizados fácilmente y puede ser útil cuando tenemos varias CPU a disposición. Simplemente necesitamos usar parallelStream() en lugar de stream() arriba. Con las transmisiones paralelas, tiene más sentido usar forEach como forEachOrdered, no haría ninguna diferencia en el rendimiento. Si queremos iterar sobre las claves, podemos usar sample.keySet() y para los valores sample.values().

¿Por qué forEachOrdered y no forEach con transmisiones?

Streams también proporcionan forEach método, pero el comportamiento de forEach es explícitamente no determinista donde como el forEachOrdered realiza una acción para cada elemento de esta corriente, en el orden encuentro de la corriente de si el flujo tiene un orden de encuentro definido. Por lo tanto, forEach no garantiza que la orden se mantendrá. También verifique this para más.

+0

No publique respuestas idénticas a preguntas múltiples. Publique una buena respuesta, luego vote/marque para cerrar las otras preguntas como duplicados. Si la pregunta no es un duplicado, * adapte sus respuestas a la pregunta. * – durron597

+0

Actualizó la respuesta en consecuencia. –

Cuestiones relacionadas