I have Map<String, Object> currencyRate that contains
"license": "https:/etc",
"timestamp": 1654,
"base": "USD",
"rates": {
"AED": 3.6,
"AFN": 88.9,
"ALL": 112,
etc
}
And e.g I want to get "AED" value which is 3.6. I've tried this:
Map<String, Object> filtered = currencyRate.entrySet()
.stream()
.filter(map->map.getValue().toString().contains("AED"))
.collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
But it returned this:
"rates": {
"AED": 3.6,
"AFN": 88.9,
"ALL": 112,
etc
}
So "rates" is key and it has values which also has keys and values. How can I get keys and values in "rates"?
Since you're using a map where each value can be any Object Map<String, Object>
(there is no declaration so I'm just assuming here), I guess you could use the findFirst
terminal operation and then cast the returned value to Map<String, Object>
(I've used Object here too for the values since the data type is not specified in the question).
Of course, this can be applied only under the strict assumption that there is only one value containing "AED" within your enclosing map (again, in the question is not specified if any other value can contain "AED").
public static void main(String[] args) {
Map<String, Object> map = new HashMap<>(Map.of(
"license", "http:/etc",
"timestamp", 1654,
"base", "USD",
"rates", Map.of(
"AED", 3.6,
"AFN", 88.9,
"ALL", 112
// ...
)
));
Map<String, Object> mapRes = (Map<String, Object>) map.entrySet()
.stream()
.filter(entry -> entry.getValue().toString().contains("AED"))
.map(entry -> entry.getValue())
.findFirst()
.orElse(null);
System.out.println(mapRes);
}
Output
{ALL=112, AED=3.6, AFN=88.9}
You don't need to use streams for that. Instead, you need to get the nested map by it key "rates"
and type cast it into the appropriate type (note that this casting is unsafe):
double aedRate = ((Map<String, Double>) map.get("rates")).get("AED");
If you want to utilize streams for that, it should be then first extract the nested map and filter out the entry:
Map.Entry<String, Double> result =
((Map<String, Double>) map.get("rates")).entrySet().stream()
.filter(entry -> entry.getKey("AED"))
.findFirst()
.orElseThrow();
Note that using Object
as generic type and operating via type casts isn't a good practice. The overall approach of a Map<String, Object>
is error-prone and unmaintainable. You would never had this problem if you kept the data in your application structured appropriately.
I guess You should use flatMap() to transform nested map to new stream.
Map<String, Object> filtered = currencyRate.entrySet()
.stream()
.filter(map->map.getValue().toString().contains("AED"))
.flatMap(map->map.stream())
.filter(...)
.collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
Comments
Post a Comment