I have Map like
for (Emp emp: findAllEmp()) {
Map<String, String> map = objectMapper.convertValue(emp, HashMap.class);
}
which has values as
projects = {projectId=24, projectName=K245}
I would like to add if projects is not null, then add this to
map.put("projectId", map.get("projects.projectId}"));
map.put("projectName",map.get("projects.projectName}"));
When I see the output, projects.projectId and projects.projectName is always null.
How do I resolve this?
And how can I dynamically add values instead of hard coding projects.projectId?
Try to understand,
projects = {projectId=24, projectName=K245} is nothing but
Map<String, Map<String,Object>>
Map<"projects", Map<"projectId",24>>
Map<"projectName",K245>>
Just iterate over a map,
Map<String, String> map = objectMapper.convertValue(emp, HashMap.class);
Map<String, Object> myMap = new HashMap<String, Object>();
if (null != map && map.size() > 0) {
for (Map.Entry<String, String> entry : map.entrySet())
myMap.put(entry.getKey(), entry.getValue());
}
myMap will contain data as
Map<"projectId",24>
<"projectName",K245>
Also you can iterate and check for value if value is instanceOf Map
Map<String, Object> myMap = null;
if (null != map && map.size() > 0) {
for (Map.Entry<String, Object> entry : map.entrySet())
if (entry.getValue() instanceof java.util.Map) {
myMap = (Map<String, Object>) entry.getValue();
}
}
or assign value to myMap and iterate over it.
Related
My parentMap is look like something below.
HashMap<String, Integer>>> parentMap = {disabled={account={test1=22}, group={test2=10}}}
What I suppose to do is, if operationType=disabled and objectType=account or group etc and testName=test1 or test2 etc then I suppose to increase the count of test1 by 1.
I have to update the same map so that at the end I should get some statistic like there are 22 tests cases of objectType=account and 10 tests cases of objectType=group etc are disabled
I tried something below but it is going in infinite loop as I'm putting values in the map and iterating over it again.
private HashMap<String, HashMap<String, HashMap<String, Integer>>> countTags(String statType, String objectType,
String opType, HashMap<String, HashMap<String, HashMap<String, Integer>>> parentMap) {
if (!Util.isEmpty(parentMap)) {
//created new map to avoid infinite loop here but no luck :(
HashMap<String, HashMap<String, Integer>> objMap = new HashMap<>();
objMap.putAll(parentMap.get(statType));
Iterator<Entry<String, HashMap<String, Integer>>> it = objMap.entrySet().iterator();
while (it.hasNext()) {
Entry<String, HashMap<String, Integer>> operationEntry = it.next();
HashMap<String, Integer> operationMap = operationEntry.getValue();
Set<String> opKeySet = operationMap.keySet();
Iterator<String> opIt = opKeySet.iterator();
while (opIt.hasNext()) {
parentMap.put(statType, countTags(objectType, opType, operationMap));
}
}
} else {
parentMap.put(statType, countTags(objectType, opType, new HashMap<String, Integer>()));
}
return parentMap;
}
private HashMap<String, HashMap<String, Integer>> countTags(String objectType, String opType, HashMap<String, Integer> tagMap) {
int testRepeatCount = tagMap.get(opType) != null ? tagMap.get(opType) : 0;
tagMap.put(opType, 1 + testRepeatCount);
HashMap<String, HashMap<String, Integer>> objMap = new HashMap<>();
objMap.put(objectType, tagMap);
return objMap;
}
I found
a.compute(key, (k, v) -> v == null ? 1 : v + 1); also some suggestions here Java map.get(key) - automatically do put(key) and return if key doesn't exist? but can I get some help how optimally I should achieve my desired outcome here?
I finally get out of my own if_else mess. this is how my final method is look a like. This helped me here Java append `HashMap` values to existing HashMap if key matches
private HashMap<String, HashMap<String, HashMap<String, Integer>>> countTags(String statType, String objectType,
String opType, HashMap<String, HashMap<String, HashMap<String, Integer>>> parentMap) {
if (!Util.isEmpty(parentMap) && parentMap.containsKey(statType)) {
// if objType is present, count the tags
if (parentMap.get(statType).containsKey(objectType)) {
HashMap<String, Integer> objMap = parentMap.get(statType).get(objectType);
HashMap<String, Integer> map = countTags(objectType, opType, objMap).get(objectType);
parentMap.get(statType).get(objectType).putAll(map);
} else {
// if objType isn't present, add that objType and count the tags
HashMap<String, HashMap<String, Integer>> map = countTags(objectType, opType,
new HashMap<String, Integer>());
parentMap.get(statType).put(objectType, map.get(objectType));
}
} else {
// first time add the new tag to calculate it's object/operation wise
// distribution
parentMap.put(statType, countTags(objectType, opType, new HashMap<String, Integer>()));
}
return parentMap;
}
Given the following situation:
Map<String, Object> map1 = new HashMap();
Map<String, String> map2 = new HashMap();
map2.put("Grp A", "a");
map2.put("Grp B", "b");
map1.put("Grp",map2);
How can get the "Grp A" value from map1 ?
Change map1 to:
Map<String, Map<String, String>> map1 = new HashMap<>();
Then map1.get("Grp").get("Grp A") will work.
Of course, in general it would be safer to store map1.get("Grp") in a variable, and check if it's not null before calling the second get():
String value = null;
Map<String, String> inner = map1.get("Grp");
if (inner != null) {
value = inner.get("Grp A");
}
If you must keep map1 as Map<String, Object> (for example, if you must store values of different types in it), you'll have to check the type of the value you got from the outer Map, and cast it to a Map before obtaining the inner value:
String value = null;
Object innerObj = map1.get("Grp");
if (innerObj instanceof Map<?,?>) {
Map<?,?> inner = (Map<?,?>) map1.get("Grp");
Object obj = inner.get("Grp A");
if (obj instanceof String) {
value = (String) obj;
}
}
Simply retrieve map2 from map1 by casting to a Map and then get the desired value from that Map:
return ((Map<String,String>)map1.get("Grp")).get("Grp A");
However, better practice would be to check that map2 isn't null before retrieving "Grp A":
Map<String,String> map = (Map<String,String>)map1.get("Grp");
if (map != null) {
return map.get("Grp A");
}
#Eran's answer would be better practice, but OP asked how to retrieve the value from the given HashMap.
Since you defined map1 as Map<String, Object> it's values are returned as objects.
You can solve this by either by .
Casting .
Map<String,String> map2 = = (Map<String,String>)map1.get("Gep")
Using the right generics for m1 .
Map<String, Map<String, String>> map1 = new HashMap<>();
Below is the solution for the above problem
import java.util.HashMap;
import java.util.Map;
public class HashMapExample {
public static void main(String[] args) {
Map<String, String> map2 = new HashMap<>();
Map<String, Map<String, String>> map1 = new HashMap<>();
map2.put("Grp A", "a");
map2.put("Grp B", "b");
map1.put("Grp",map2);
System.out.println(map1.get("Grp").get("Grp A"));
}
}
Hope this will work
Thanks...
I have the LinkHashMap here.
Map<String, String> map
{011A=HongKong, 012B=London, 015Y=NewYork, 312=China, 272=Canada}
I would like to filter or arrange the map to be this,
Only the key with a 3 digit or length = 3 kept in the map.
{312=China, 272=Canada}
What kind of method could I use?
Thank you very much!
You can use the Iterator
Iterator<String> it = map.keySet().iterator();
while (it.hasNext())
{
String s = it.next();
if(s.length() != 3){
it.remove();
}
}
If you are using Java 8 (or higher) there is a convenient feature called Lambda that provides a nice api to work with streams.
To create a second map with only the filtered keys use this below code:
Map<String, String> originMap;
Map<String, String> filteredmap = originMap.entrySet().stream()
.filter(x -> x.getKey().length() == 3)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
If you want to remove the elements from your map itself :
Map<String, String> map;
map.entrySet().removeIf(entry -> entry.getKey().length != 3);
You can write a method like this to filter,
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>() {{
put("011A", "HongKong");
put("012B", "London");
put("015Y", "NewYork");
put("312", "China");
put("272", "Canada");
}};
Map<String, String> filteredMap = filterMap(map);
}
static Map<String, String> filterMap (Map<String, String> map) {
HashMap<String, String> filteredMap = new HashMap<>();
for (String key: map.keySet()) {
if (key.length() == 3) {
filteredMap.put(key, map.get(key));
}
}
return filteredMap;
}
}
For Java >= 8:
public static Map<String, String> filterMap(Map<String, String> map) {
return map.entrySet().stream()
.filter(entry -> entry.getKey().length() == 3)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
For Java < 8:
public static Map<String, String> filterMap(Map<String, String> map) {
Map<String, String> res = new HashMap<>();
for (Map.Entry<String, String> entry : map.entrySet())
if (entry.getKey().length() == 3)
res.put(entry.getKey(), entry.getValue());
return res;
}
Im having a List> as
[{TXNO=428, STATUS=NEW}, {TXNO=434, STATUS=NEW}, {TXNO=442, STATUS=NEW}]
I'm iterating the object as
for (Map<String, Object> map : details) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
logger.info(key+"="+value);
}
}
It prints as
TXNO=428
STATUS=NEW
TXNO=434
STATUS=NEW
TXNO=442
STATUS=NEW
How can I add TXNO values in a list? My List object finally should be [428,434, 442]
List<String> TXNOList = new LinkedList<String>();
for (Map<String, Object> map : details) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
logger.info(key+"="+value);
if(key.equals("TXNO")) {
TXNO.add(value);
}
}
}
If you need a Integer list just change the TXNOList definition to Integer and cast value to Integer: Integer.valueOf(value).
If you can use java 8, then here's an elegant solution:
List<Object> txno = mapList.stream()
.map(map -> map.get("TXNO")) // get value by key
.filter(Objects::nonNull) // check if not null
.collect(Collectors.toList()); // collect to list
You can do this way :-
List<Object> TXList=new ArrayList<Object>();
for (Map<String, Object> map : details) {
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
if(key.equals("TXNO"))
TXList.add(value);
}
}
I'm having problems working out how to iterate this structure.
ArrayList<HashMap<String, HashMap<String, String>>> list
Can you help me work out how to walk the complete structure?
Here's what I've got to so far but where do I go next? I need to get all the way down to the deepest data.
for (HashMap<String, String> map : data)
for (Entry<String, String> entry : map.entrySet())
How about this?
ArrayList<HashMap<String, HashMap<String, String>>> list = new ArrayList<>();
for (HashMap<String, HashMap<String, String>> m : list) {
for (Map.Entry<String, HashMap<String, String>> e : m.entrySet()) {
String key1 = e.getKey();
for (Map.Entry<String, String> me : e.getValue().entrySet()) {
String key2 = me.getKey();
String value = me.getValue();
}
}
}
Note that you really should be using the interface form of the objects:
List<Map<String, Map<String, String>>> list = new ArrayList<>();
for (Map<String, Map<String, String>> m : list) {
// All Maps.
for (Map.Entry<String, Map<String, String>> e : m.entrySet()) {
// Outer key.
String key1 = e.getKey();
for (Map.Entry<String, String> me : e.getValue().entrySet()) {
// Inner key.
String key2 = me.getKey();
// The String value.
String value = me.getValue();
}
}
}