I have mainHolder map which contains another map holder as value I am facing problem when clearing the holder map that I am loosing the vlue of the apple key in the mainHolder map.
How can I Keep the value of the mainHolder map after Clearing the holder map?
Code
import java.util.HashMap;
import java.util.LinkedHashMap;
public class Generator {
public static void main(String[] args) {
LinkedHashMap<String, Object> holder = new LinkedHashMap<String, Object>();
final HashMap<String, LinkedHashMap<String, Object>> mainHolder = new LinkedHashMap<String, LinkedHashMap<String, Object>>();
holder.put("firstName", "Alex");
holder.put("lastName", "Cruz");
mainHolder.put("apple", holder);
holder.clear(); //After Clearing the map I am loosing the value in the mainHolder for 'apple'
holder.put("quantity", 13);
mainHolder.put("apple", holder);
System.out.println("Test");
}
}
mainHolder
should contain at the end the following:
[apple:[firstName: Fadi, lastName: Cruz, quantity:13]]
The reason this is happening is because you are using the same key.
If the map previously contains a mapping for the key, the old value
is replaced.
Update
<>.add(map) will put a reference to map in the list, so it's not a
copy. When you then do map.clear() afterwards, it erases the content
of the map in the list too, because it is the very same object. Do
<>.add(map.clone()) instead or (preferably) do map = new HashMap<>();
solution
LinkedHashMap<String, Object> holder = new LinkedHashMap<String, Object>();
final HashMap<String, LinkedHashMap<String, Object>> mainHolder = new LinkedHashMap<String, LinkedHashMap<String, Object>>();
holder.put("firstName", "Alex");
holder.put("lastName", "Cruz");
mainHolder.put("apple", holder);
holder = new LinkedHashMap<>();
LinkedHashMap<String, Object> temp = mainHolder.get("apple");
temp.put("quantity",13);
mainHolder.put("apple",temp);
System.out.println(mainHolder);
Related
Im storing 2 map with different structure in single map like below,
Map<String, List<String>> colMap = new HashMap<String, List<String>>();
Map<String, String> appMap = new HashMap<String, String>();
// colMap assigning some values
// appMap assigning some values
Map<String, Map> mainMap = new HashMap<String, Map>();
mainMap.put("appMap", appMap);
mainMap.put("colMap", colMap);
I want to get map one by one and iterate the map.
If I try get map like below, getting error,
.......
Map colMap = map.get("colMap");
for(Entry<String, List<String>> entry : colMap.entrySet())
Error: Type mismatch: cannot convert from element type Object to Map.Entry<String,List<String>>
Why not just create a simple container POJO class (or record in Java 16+) for the two maps instead of mainMap and keep the relevant type-safety which to do it Java-way?
public class MapPojo {
private final Map<String, List<String>> colMap;
private final Map<String, String> appMap;
public MapPojo(Map<String, List<String>> colMap, Map<String, String> appMap) {
this.colMap = colMap;
this.appMap = appMap;
}
// getters, etc.
}
MapPojo mainMap = new MapPojo(colMap, appMap);
Error you are getting because when you are doing map.get operation your reference is Just Map without any Generics which will treated as Object class's reference. You should use generics like below and it will work -
Map<String, List<String>> colMap = map.get("colMap");
for(Entry<String, List<String>> entry : colMap.entrySet())
I have two nested maps and I try to merge two nested maps and produce a output of two merged HashMap. Below is the code that I use:
HashMap<String, Object> map = new HashMap<>();
HashMap<String, Object> map1 = new HashMap<>();
map1.put("location", "A");
HashMap<String, Object> map2 = new HashMap<>();
map2.put("geocoordinates", map1);
HashMap<String, Object> map3 = new HashMap<>();
map3.put("TEST", map2);
map.putAll(map3);
HashMap<String, Object> map11 = new HashMap<>();
map11.put("longitude", "B");
HashMap<String, Object> map12 = new HashMap<>();
map12.put("geocoordinates", map11);
HashMap<String, Object> map13 = new HashMap<>();
map13.put("TEST", map12);
map.putAll(map13);
System.out.println(map);
The output that I get is:
{TEST={geocoordinates={longitude=B}}}
But I expected both longitude and location key to be nested inside geocoordinates key but only longitude B is there. So, How can I get the combined. How achieve this?
Do it as follows:
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Object> map = new HashMap<>();
HashMap<String, Object> map1 = new HashMap<>();
map1.put("location", "A");
HashMap<String, Object> map2 = new HashMap<>();
map2.put("geocoordinates", map1);
HashMap<String, Object> map3 = new HashMap<>();
map3.put("TEST1", map2);
map.putAll(map3);
HashMap<String, Object> map11 = new HashMap<>();
map11.put("longitude", "B");
HashMap<String, Object> map12 = new HashMap<>();
map12.put("geocoordinates", map11);
HashMap<String, Object> map13 = new HashMap<>();
map13.put("TEST2", map12);
map.putAll(map13);
System.out.println(map);
}
}
Output:
{TEST2={geocoordinates={longitude=B}}, TEST1={geocoordinates={location=A}}}
Reason: a Map replaces the old value when you put a new value on the same key (in your case, it is TEST). Note that HashMap.putAll() copies all of the mappings from one map into another. In your code, map.putAll(map3) is equivalent of map.put("TEST",map3). And, map.putAll(map13) is equivalent of map.put("TEST",map13) which replaces the earlier value, map3 because of the same key, TEST.
Update: Adding the following update based on the new requirement mentioned in your comment
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class Main {
public static void main(String[] args) {
HashMap<String, Object> map = new HashMap<>();
List<HashMap> list=new ArrayList<HashMap>();
HashMap<String, Object> map1 = new HashMap<>();
map1.put("location", "A");
list.add(map1);
HashMap<String, Object> map11 = new HashMap<>();
map11.put("longitude", "B");
list.add(map11);
HashMap<String, Object> map2 = new HashMap<>();
map2.put("geocoordinates", list);
map.put("TEST",map2);
System.out.println(map);
}
}
Output:
{TEST={geocoordinates=[{location=A}, {longitude=B}]}}
Another way of doing it as follows:
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Object> map1 = new HashMap<>();
map1.put("location", "A");
map1.put("longitude", "B");
HashMap<String, Object> map2 = new HashMap<>();
map2.put("geocoordinates", map1);
HashMap<String, Object> map = new HashMap<>();
map.put("TEST", map2);
System.out.println(map);
}
}
Output:
{TEST={geocoordinates={location=A, longitude=B}}}
The behavior you're seeing is correct – namely, if you have a map and store a new value for an existing key, the old value will be lost.
Here's a simple example that isolates what you're doing. In this code, the initial value "one" will be overwritten by "two". This is how maps work. In your case, you're using other maps instead of simple strings, but the behavior is the same – you have one value and you're replacing it with another value.
HashMap<String, Object> map = new HashMap<>();
map.put("TEST", "one");
map.put("TEST", "two");
To retain both "one" and "two", you need to either use different keys (ex: "TEST1" and "TEST2"), or alter one of the nested maps stored under "TEST", or introduce an altogether different data structure (such as a java.util.Set).
I have an outerMap which contains an innerMap for each key it got. At first, every innerMap is the same (here, they contain {1=1}.
I want to change the value of one certain innermap, for a certain key.
Here is my code:
public class HelloWorld
{
public static void main(String args[]){
HashMap<String, HashMap<String, Integer>> outerMap = new HashMap<String, HashMap<String, Integer>>();
HashMap<String, Integer> innerMap = new HashMap<String, Integer>();
outerMap.put("1001",innerMap);
outerMap.put("1002",innerMap);
outerMap.put("1003",innerMap);
innerMap.put("1", 1);
//My attempt to change only one innermap;
Map<String, Integer> map_to_change = outerMap.get("1001");
map_to_change.put("1", 0);
//And then I print them to see if it's working;
for(Map.Entry map : outerMap.entrySet() )
{
System.out.println(map.getKey()+" "+map.getValue());
}
}
}
However, the output here is
1003 {1=0}
1002 {1=0}
1001 {1=0}
Which shows that my code changes all innermaps, and not only the one linked with the key "1001".
What can I do?
You are pointing the same innerMap object in the outerMap,
outerMap.put("1001",new HashMap<String, Integer>());//create separate maps
outerMap.put("1002",new HashMap<String, Integer>());
outerMap.put("1003",new HashMap<String, Integer>());
HashMap<String, Integer> innerMap =outerMap.get("1001");//get the map you want to put value
innerMap.put("1", 1);//assign the value
Update:
If you want to retain a copy of Map which you have already created, you can copy and create a new Map from it using putAll method,
outerMap.put("1001",copyMap(innerMap));
outerMap.put("1002",copyMap(innerMap));
outerMap.put("1003",copyMap(innerMap));
copyMap method looks like,
private static HashMap<String, Integer> copyMap(HashMap<String, Integer> innerMap){
HashMap<String, Integer> copiedInnerMap = new HashMap<String, Integer>();
copiedInnerMap.putAll(innerMap);
return copiedInnerMap;
}
I am adding few item on finalMapNode using map for creating json for d3. and i dont want any duplicates item. how to check.finalmapNode put the duplicates item on map.I dont want duplicated item.if item is avalible then it should not put on map . if id is avalable then item should not put in the finalmapnode.
Note::if id is avalable then item should not put in the finalmapnode.
List<Map<String, Object>> listNodeMap = new ArrayList<Map<String, Object>>();
Map<String, Object> finalMapNode2 = new TreeMap<String, Object>();
Map<String, Object> finalMapNode = new TreeMap<String, Object>();
//if id is avalable then item should not put in the finalmapnode.
finalMapNode.put("id", Integer.parseInt(source2.get(z))+"");
finalMapNode.put("name",source.get(z));
finalMapNode.put("displayname", source.get(z));
finalMapNode.put("image", "/xxxxx/resources/icon/location.png");
finalMapNode.put("type", "location");
finalMapNode.put("group", 0);
finalMapNode.put("opacity", 100);
finalMapNode2.put("id", Integer.parseInt(target2.get(z))+"");
finalMapNode2.put("name",target.get(z));
finalMapNode2.put("displayname", target.get(z));
finalMapNode2.put("image", "/xxxxx/resources/icon/location.png");
finalMapNode2.put("type", "location");
finalMapNode2.put("group", 0);
finalMapNode2.put("opacity", 100);
listNodeMap.add(finalMapNode);
listNodeMap.add(finalMapNode2);
When you try to add the KEY which is already available in the hashmap, then it will override the previous KEY's VALUE and adds the new VALUE. So its up to you to validate the map before trying to add the KEY and VALUE. You can use finalmapnode.containsKey(KEY); to validate and then add the VALUES.
EDIT
Just check the below method works for you!
private static void putMap(String strKey, Object object, Map<String, Object> map){
if(!map.containsKey(strKey)){
map.put(strKey, object);
}
}
In your case, instead of using
finalMapNode.put("name",source.get(z));
you can use
putMap("name",source.get(z), finalMapNode);
The above method will not override the values if you add duplicate KEYS. Pass the KEY, VALUE and the Map which you declared as finalMapNode.
Try this and see.
Thanks!
HashMap<String, String> map = new HashMap<String, String>();
map.put("A", "1");
map.put("B", "2");
map.put("C", "2");
map.put("D", "3");
map.put("E", "3");
HashMap<String, String> mapNew = new HashMap<String, String>();
for(String s :map.keySet())
{
//String value = map.get(s);
System.out.println(s +"=="+map.get(s));
if(!mapNew.containsValue(map.get(s)))
{
mapNew.put(s, map.get(s));
}
}
System.out.println(mapNew);
before :{A=1,B=2,c=2,D=3,E=3}
Output after removing duplicates : {A=1,B=2,D=3}
In my code i have a
Map<String,Map<String,customObject>>
I am not sure how to iterate over this map and get the values from it.
What i am trying to do here is get the enclosing Map by passing in the key to the external Map.
When i get the enclosing map i need to iterate over it and get key and value from it.
Can you please let me know how i can do this as i am kind of stuck here.
Any example or code of a similar type can be of a great help to understand it better.
Thanks
Vikeng21
You can use the entry set of both Maps. something like this:
Map<String,Map<String,String>> map1 = ...
Set<Entry<String,Map<String,customObject>>> entrySet1 = map1.entrySet();
for (Entry<String, Map<String, customObject>> entry1 : entrySet1) {
Map<String,String> map2 = entry1.getValue();
Set<Entry<String, customObject>> entrySet2 = map2.entrySet();
for (Entry<String, customObject> entry2 : entrySet2) {
System.out.println(entry1.getKey() +" -> "+entry2.getKey()+" -> "+entry2.getValue());
}
}
To iterate over hashmap entries...
for (Map.Entry<String, Map<String, Object>> ent : hashmap.entrySet())
{
//ent.getKey(); is the key [String]
//ent.getValue(); is the value [Map<String, Object>]
}
Now work out from there, it's basically the same.
I am not sure how to iterate over this map and get the values from it
You would iterate over the map's values like with any maps - see below an example that uses such a structure.
Map<String, CustomObject> innerMap = new HashMap<String, CustomObject> ();
innerMap.put("abc", new CustomObject());
Map<String, Map<String, CustomObject>> externalMap = new HashMap<String, Map<String, CustomObject>> ();
externalMap.put("map1", innerMap);
//iterate over all the maps contained in externalMap
for (Map<String, CustomObject> inner : externalMap.values()) {
System.out.println(inner);
}
If you also need to access the keys, you can iterate over the entry set:
for (Entry<String, Map<String, CustomObject>> e : externalMap.entrySet()) {
System.out.println(e.getKey()); //map1
System.out.println(e.getValue()); //innerMap
}
I think this example will give your answer....
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public class MapInMap {
public static void main(String[] args) {
Map<String, MyObj> innerMap01 = new HashMap<String, MyObj>();
Map<String, MyObj> innerMap02 = new HashMap<String, MyObj>();
innerMap01.put("OneOne", new MyObj());
innerMap02.put("TwoOne", new MyObj());
Map<String, Map<String, MyObj>> maps = new HashMap<String, Map<String, MyObj>>();
maps.put("One", innerMap01);
maps.put("Two", innerMap02);
for (Entry<String, Map<String, MyObj>> map : maps.entrySet()) {
for (Entry<String, MyObj> innerObject : map.getValue().entrySet()) {
// your logic
}
}
}
}
class MyObj {
int i;
}