Home > front end >  How to filter nested Map<String, Object> in java?
How to filter nested Map<String, Object> in java?

Time:06-05

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"?

CodePudding user response:

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()));

CodePudding user response:

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}
  • Related