Reputation: 7
What do you think is the best way to find a value in a map inside another map.
Map <String, String> map1 = new HashMap<>();
map1.put("map1|1", "1.1");
map1.put("map1|2", "1.2");
map1.put("map1|3", "1.3");
map1.put("map1|4", "1.4");
Map <String, String> map2 = new HashMap<>();
map2.put("map2|1", "2.1");
map2.put("map2|2", "2.2");
map2.put("map2|3", "2.3");
map2.put("map2|4", "2.4");
Map<String, Map> mapOfMaps = new HashMap<>();
mapOfMaps.put("MAP|map1", map1);
mapOfMaps.put("MAP|map2", map2);
Now if I need the value of "MAP|map2" (inside mapOfMaps) and "map2|3" (inside map2) will be "2.3"
I tried to do something like:
System.out.println("x="+getValue(mapOfMaps,"MAP|map2", "map2|4"));
public static String getValue (Map<String, Map> map,String mapfind, String val) {
Map<Object, Object> mp = map.entrySet().stream()
.filter(x -> x.getKey().equals(mapfind))
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
System.out.println("--------"+mp);
return (String) mp.get(val);
}
but the result is:
--------{MAP|map2={map2|1=2.1, map2|4=2.4, map2|2=2.2, map2|3=2.3}}
x=null
Can you help me with some ideas?
Upvotes: 0
Views: 2438
Reputation: 3600
I think the easiest way to get your desired output would be to use map.get(mapfind).get(val)
. But if you want to achieve it using your existing code, you could call values()
on the collected map
and call filter to get a second level filter. Below is the code snippet of your modified method
public static String getValue(Map<String, Map> map, String mapfind, String val) {
Map mp = map.entrySet().stream().filter(x -> x.getKey().equals(mapfind))
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()))
.values().stream().filter(y -> y.containsKey(val)).findAny().orElse(null);
System.out.println("--------" + mp);
if (mp == null)
return "";
return (String) mp.get(val);
}
Upvotes: 0
Reputation: 537
public static String getValue (Map<String, Map> map,String mapfind, String val) {
Map childMap = map.get(mapfind);
if (childMap == null) {
return null;
}
return childMap.containsKey(val) ? childMap.get(val).toString() : null;
}
Upvotes: -1
Reputation: 5173
Instead of declaring mapOfMaps
by its raw type it should be defined as
Map<String, Map<String, String>> mapOfMaps = new HashMap<>();
The corresponding getValue
method would look like this:
public static String getValue(Map<String, Map<String, String>> mapOfMaps, String mapfind, String val) {
Map<String, String> innerMap = mapOfMaps.get(mapfind);
return innerMap != null ?
innerMap.get(val) :
null;
}
Using Optional
we can write it as follows:
public static String getValue(Map<String, Map<String, String>> mapOfMaps, String mapfind, String val) {
return Optional.ofNullable(mapOfMaps.get(mapfind))
.map(m -> m.get(val))
.orElse(null);
}
If we kept mapOfMaps
declared by its raw type we would get in the first version of getValue
a type safety warning about an unchecked conversion and in the second version we would need explicitly cast the result to String
. Since we use mapOfMaps
only to map String
keys to String
values we should declare it accordingly.
Further reading: What is a raw type and why shouldn't we use it?
Upvotes: 3