Estoy tratando de agregar valor a la Lista que está almacenada en HashMap y que tiene una Lista principal.
Cuando trato de hacerlo, aparece "El método de ingreso de tipo no es compatible con la Lista"
Estoy probando el siguiente código, la lógica es:
List < HashMap > txnvalues = new ArrayList < HashMap > (); for (LinkedHashMap < String, Object > linkedHashMap: resultset) { HashMap data = new HashMap < > (); HashMap attrData = new HashMap < > (); List values = new ArrayList < > (); data.put("values", new ArrayList < > ()); attrData.put("attrID", linkedHashMap.get("ID")); attrData.put("attrVal", linkedHashMap.get("VAL")); String txnID = linkedHashMap.get("T_ID").toString(); if (!txnvalues.stream().anyMatch(list -> list.containsValue(txnID))) { data.put("tID", linkedHashMap.get("T_ID")); values.add(attrData); data.put("Values", values); txnvalues.add(data); } else { txnvalues.get("Values").add(attrData); // this Line throws error } }Ejemplo :
[{ "tID":123, "Values":[{attrID:1,attrVal:123}] }] //Here If linkedHashmap.get("T_ID") = 123 which matches with tID then I want to add data in the Values [{ "tID":123, "Values":[{attrID:1,attrVal:123},{attrID:11,attrVal:467}] }] //If it doesn't match then I want to create new Hashmap and update txnValues Like this [{ "tID":123, "Values":[{attrID:1,attrVal:123},{attrID:2,attrVal:3435}] }, { "tID":456, "Values":[{attrID:2,attrVal:233}] } ]Decidí parametrizar todos sus diversos iterables. A continuación se muestra el código parametrizado.
List<HashMap<String, List<HashMap<String, Object>>>> txnvalues = new ArrayList<HashMap<String, List<HashMap<String, Object>>>>(); for (LinkedHashMap<String, Object> linkedHashMap : resultset) {//Error here HashMap<String, List<HashMap<String, Object>>> data = new HashMap<String, List<HashMap<String, Object>>>(); HashMap<String, Object> attrData = new HashMap<String, Object>(); List<HashMap<String, Object>> values = new ArrayList<HashMap<String, Object>>(); data.put("values", new ArrayList<>()); attrData.put("attrID", linkedHashMap.get("ID")); attrData.put("attrVal", linkedHashMap.get("VAL")); String txnID = linkedHashMap.get("T_ID").toString(); if (!txnvalues.stream().anyMatch(list -> list.containsValue(txnID))) { data.put("tID", linkedHashMap.get("T_ID")); //Error here values.add(attrData); data.put("Values", values); txnvalues.add(data); } else { txnvalues.get("Values").add(attrData); //Error here } } Primero, tiene varios errores en su código, como intentar poner una clave de cadena y un valor de objeto en data , que es un HashMap que solo toma una clave de cadena y un valor de lista (de HashMaps de cadenas y objetos). Otro ejemplo es intentar obtener un elemento de txnvalues mediante una cadena, cuando txnvalues es una lista y, por lo tanto, requiere un parámetro de índice entero.
En segundo lugar, aquí tiene una variable que nunca se define: resultset . No sabemos qué es ni cómo se usa, ya que nunca se menciona en ningún otro lugar.
Tercero, hay muchas maneras de manejar conjuntos anidados. Este >-> List<HashMap<String, List<HashMap<String, Object>>>> es simplemente horrible.
Vuelva a escribir su código de manera que sea legible, parametrizado y pueda compilarse correctamente sin errores. Solo parametrizar lo ayudará a realizar un seguimiento de qué iterables toman qué parámetros y ayudará a prevenir el problema que tuvo cuando vino aquí en busca de ayuda.
En el bloque else , llama al método get de txnvalues que es una lista de HashMap s y, por lo tanto, espera un índice entero. Creo que asume que en este punto tiene una referencia al HashMap al que agregaría los valores. Pero no lo haces.
Por lo tanto, debe encontrar el índice donde agregar los valores, lo que significa que debe revisar la lista de txnvalues nuevamente.
Por esta razón, debe utilizar un enfoque diferente:
txnvalues.stream() .filter(m -> m.get("tID").equals(txnID)) .findFirst() .ifPresentOrElse( m -> m.get("Values").add(attrData), () -> { HashMap data = new HashMap<>(); // Other stuff to fill the data txnvalues.add(data); } ); Aquí .filter(m -> m.get("tID").equals(txnID)) corresponde a su .anyMatch(list -> list.containsValue(txnID)) (la list de parámetros es en realidad una instancia de HashMap ).
Cambié la condición: de acuerdo con su muestra de datos, está buscando un Map que tenga un valor txnID para la clave "tID" , por lo tanto, obtener el valor de esta clave es más rápido que mirar todos los valores en el HashMap . (Puede devolver null ).
Por lo tanto, el filter devolverá solo las entradas que contengan el valor requerido de la clave "tID" . Luego .findFirst() "devuelve" la referencia a ese HashMap . Ahora .ifPresentOrElse realiza las acciones que desea:
m.get("Values").add(attrData) en la lista; esto corresponde a su única línea de código en el bloque else ;if : si no se encuentra nada, cree la nueva instancia.