'How I can access and add value from the list which is nested in the hashmap and list in Java
I am trying to add value for the List which is stored in HashMap and that has one parent List.
When I try to do so I get "The method get in type is not compatible with the List"
I am trying the following code, logic is :
- If I get the matching value of tID in the txnValue List I am just adding the "Values" List otherwise I am creating the new HashMap.
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
}
}
Example :
[{
"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}]
}
]
Solution 1:[1]
I decided to parameterize all of your various iterables. Below is the parameterized code.
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
}
}
First, you have multiple errors in your code such as trying to put a String key and Object value into data, which is a HashMap that only takes a String key and a List(of HashMaps of Strings and Objects) value. Another such is trying to get an item from txnvalues by a String, when txnvalues is a List and therefore requires an integer index parameter.
Second, you have a variable here which is never defined: resultset. We don't know what it is or how it is used, since it's never referenced elsewhere.
Third, there are many many ways to handle nested sets. This >-> List<HashMap<String, List<HashMap<String, Object>>>> is simply horrible.
Please re-write your code in a way that is readable, parameterized, and can properly compile without errors. Just parameterizing will help you keep track of which iterables take which parameters and will help prevent the problem you had when you came here for help.
Solution 2:[2]
In the else block, you call get method of txnvalues which a list of HashMaps and thus it expects an integer index. I believe you assume that at this point you've got a reference to the HashMap to which you would add the values. But you don't.
So, you need to find the index where to add the values, which means you have to look through the txnvalues list again.
For this reason, you should use a different approach:
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);
}
);
Here .filter(m -> m.get("tID").equals(txnID)) corresponds to your .anyMatch(list -> list.containsValue(txnID)) (the parameter list is actually instance of HashMap).
I changed the condition: according to your data sample, you looking for Map which has txnID value for the "tID" key, therefore getting the value of this key is faster than looking through all the values in the HashMap. (It may return null.)
So filter will return only the entries which contain match the required value of the "tID" key. Then .findFirst() “returns” the reference to that HashMap. Now .ifPresentOrElse performs the actions you want:
m.get("Values").add(attrData)into the list; this corresponds your one line of code in theelseblock;- the other code is what you had in the
ifblock: if nothing is found, create the new instance.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Blue Dev |
| Solution 2 | Alexey Ivanov |
