¿Cómo para cada hashmap? [duplicate]

8 minutos de lectura

avatar de usuario
Mediador

tengo este campo:

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

Para cada Hash<String, HashMap> necesito crear un ComboBoxcuyos elementos son el valor (que resulta ser un HashMap en sí mismo) de HashMap <String, **HashMap**>.

A modo de demostración (que no funciona):

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

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

    – Nitin Mahesh

    25 de julio de 2015 a las 17:48

  • Java 8 usando flujos: stackoverflow.com/a/32343195/1216775, una ventaja con los flujos es que también se pueden paralelizar.

    – akhil_mittal

    27 de septiembre de 2018 a las 4:40

avatar de usuario
cirilo n

Sé que llego un poco tarde para eso, pero también compartiré lo que hice, en caso de que ayude a alguien más:

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

  • Nunca recuerdo cómo escribir esto, así que siempre vuelvo a esta misma respuesta. Votó a favor, porque esta es una respuesta limpia y este código está copiado y pegado en tantos lugares en mis proyectos, ¡gracias!

    – Katu

    23 de enero de 2015 a las 10:53

  • @Katu simplemente escriba yourmap..entrySet().for y el autocompletado de IDE lo manejará.

    – AITAALI_ABDERRAHMANE

    11 de septiembre de 2017 a las 10:18

avatar de usuario
Nitin Mahesh

lambda Expresión Java 8

En Java 1.8 (Java 8) esto se ha vuelto mucho más fácil usando para cada método de operaciones agregadas (Operaciones de transmisión) que se parece a los iteradores de Iterable Interfaz.

Simplemente copie y pegue la siguiente declaración en su código y cambie el nombre del mapa hash variable de mmm a su variable HashMap para imprimir el 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í hay un ejemplo donde un expresión lambda se utiliza:

    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 uno puede usar Separador por lo mismo.

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

ACTUALIZAR


Incluyendo enlaces de documentación a Oracle Docs. Para más información lambda ve a esto Enlace y debe leer Operaciones Agregadas y para Spliterator ve a esto Enlace.

  • y supongo que no podemos las variables locales dentro del alcance adjunto sin declararlas finales. Obtuvo Local variable schedule defined in an enclosing scope must be final or effectively final mientras usa la variable declarada fuera del cuerpo lambda, a diferencia de los cierres en Groovy.

    – Mahesha999

    16 dic 2016 a las 14:32


  • La desventaja de usar lambdas es que no puede devolver el otro método, mientras está dentro de lambda.

    – apsciencia

    30 de marzo de 2017 a las 5:37

  • ¿Cuál es el uso de spliterator aquí? ¿Está utilizando flujos paralelos?

    – akhil_mittal

    10 oct 2018 a las 12:47

  • Si está trabajando en Android, cada llamada mencionada aquí requiere el nivel de API 24.

    – A.J.

    13 de marzo a las 11:19

avatar de usuario
Berto F.

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: este es un enfoque más ordenado que mi respuesta (suponiendo que estamos usando Java 5 o posterior)

    –Oliver Charlesworth

    20 de noviembre de 2010 a las 21:05

  • El uso de argumentos genéricos en el HashMap externo parecería indicar Java 5 o posterior. [[ But I did wonder about what Java this was since the inner HashMap didn’t have generic args and there was an array access done on a HashMap… but its just some “pseudo” code for conveying the question. ]]

    – Berto F.

    20 de noviembre de 2010 a las 21:17

  • ¿Te importa explicar por qué no parece funcionar para ti? ¿Está utilizando Java 5 o posterior? Estamos siguiendo su ejemplo de código, que no parece hacer nada con el cuadro combinado una vez creado. ¿O los valores no están en el orden que desea? ¿O necesitaba las claves en lugar de los valores en el cuadro combinado? Creo que la mayoría estaría de acuerdo en que cualquiera de las 3 respuestas hasta ahora debería funcionar bien, por lo que es probable que haya un problema al aplicar la respuesta u otro problema en otro lugar con el que podamos ayudar si nos brinda más información.

    – Berto F.

    20 de noviembre de 2010 a las 21:20


  • ooohh…que estupidez =). Solo una pregunta sobre cómo obtener HashMapString, HashMap>

    – Mediador

    20 de noviembre de 2010 a las 21:34

  • @simply denis – Me temo que no entiendo tu pregunta. ¿Estás preguntando cómo obtienes una referencia a HashMap<String, HashMap<SomeInnerKeyType, String>>? Si su ciclo está en un método, debería poder usar this.selects o simplemente selects? De lo contrario, debe pasar el mapa como parámetro al método que contiene el bucle. ¿O está preguntando cómo obtener un interior específico? HashMap<SomeInnerKeyType, String> para una clave dada (this->String?) Usted usaría selects.get(keyString). Si estoy completamente mal entendido, por favor aclare.

    – Berto F.

    20 de noviembre de 2010 a las 23:23

avatar de usuario
akhil_mittal

Transmite Java 8

Junto con forEach método que acepta un expresión lambda también tenemos corriente API, en Java 8.

Iterar sobre las entradas (Usando forEach y Streams):

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 los flujos es que se pueden paralelizar fácilmente y pueden ser útiles cuando tenemos varias CPU a disposición. Simplemente necesitamos usar parallelStream() en lugar de stream() arriba. Con flujos paralelos tiene más sentido usar forEach como forEachOrdered no haría ninguna diferencia en el rendimiento. Si queremos iterar sobre claves podemos usar sample.keySet() y por valores sample.values().

Por qué forEachOrdered y no forEach con arroyos?

Los flujos también proporcionan forEach método sino el comportamiento de forEach es explícitamente no determinista donde como el forEachOrdered realiza una acción para cada elemento de este flujo, en el encuentro orden de la corriente si la secuencia tiene un orden de encuentro definido. Asi que forEach no garantiza que el pedido se mantendría. También revisa esto para más.

Puede iterar sobre un HashMap (y muchas otras 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());
}

  • No puedo con tal diseño hasta el nivel inferior.

    – Mediador

    20 de noviembre de 2010 a las 21:17

  • @Sí tu puedes. Puede crear un iterador interno basado en it.next().

    –Oliver Charlesworth

    20 de noviembre de 2010 a las 21:22

avatar de usuario
panahí

Generalmente hago lo mismo que cx42net, pero no creo 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 me parece lo más intuitivo, creo que tengo prejuicios contra la iteración de los valores de un mapa.

  • No puedo con tal diseño hasta el nivel inferior.

    – Mediador

    20 de noviembre de 2010 a las 21:17

  • @Sí tu puedes. Puede crear un iterador interno basado en it.next().

    –Oliver Charlesworth

    20 de noviembre de 2010 a las 21:22

avatar de usuario
Suresh Maidaragi

Usar entrySet,

/**
 *Output: 
D: 99.22
A: 3434.34
C: 1378.0
B: 123.22
E: -19.08

B's new balance: 1123.22
 */

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MainClass {
  public static void main(String args[]) {

    HashMap<String, Double> hm = new HashMap<String, Double>();

    hm.put("A", new Double(3434.34));
    hm.put("B", new Double(123.22));
    hm.put("C", new Double(1378.00));
    hm.put("D", new Double(99.22));
    hm.put("E", new Double(-19.08));

    Set<Map.Entry<String, Double>> set = hm.entrySet();

    for (Map.Entry<String, Double> me : set) {
      System.out.print(me.getKey() + ": ");
      System.out.println(me.getValue());
    }

    System.out.println();

    double balance = hm.get("B");
    hm.put("B", balance + 1000);

    System.out.println("B's new balance: " + hm.get("B"));
  }
}

ver ejemplo completo aquí:

  • Definitivamente funciona, lo uso todos los días 🙂 ¿Qué es exactamente lo que no funciona? Ya que tienes HashMap<String, HashMap>, necesitaría dos bucles: uno para el HashMap externo y otro para el interno. Por cierto, definitivamente debe escribir el segundo HashMap, no sé qué almacena en él, pero algo como HashMap>, aunque, según su ejemplo, parece que debería usar HashMap<String, Set<String>>. Y otra cosa: use interfaces: Map<String, Map> cuando pueda.

    – icyrock.com

    20 de noviembre de 2010 a las 21:27

¿Ha sido útil esta solución?