Mediador
tengo este campo:
HashMap<String, HashMap> selects = new HashMap<String, HashMap>();
Para cada Hash<String, HashMap>
necesito crear un ComboBox
cuyos 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);
}
}
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
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
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 HashMap
String, 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 usarthis.selects
o simplementeselects
? 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íaselects.get(keyString)
. Si estoy completamente mal entendido, por favor aclare.– Berto F.
20 de noviembre de 2010 a las 23:23
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
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
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
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