Home > Blockchain >  java 8 grouping a map of same key and value and make a key value pair
java 8 grouping a map of same key and value and make a key value pair

Time:02-11

I have a method fetchConfigsCount() which returns List<Map<String, Object>>.

The result looks like:

                    {
                        "web_id": "abc",
                        "count": 1
                    },
                    {
                        "web_id": "xyz",
                        "count": 1
                    },
                    {
                        "web_id": "pqr",
                        "count": 1
                    }

We have another method fetchWebsitesCount() which also returns a response in same format.

web_id is the key and its value is owner name. count is another key and its value is of type int.

                    {
                        "web_id": "abc",
                        "count": 2
                    },
                    {
                        "web_id": "xyz",
                        "count": 3
                    },
                    {
                        "web_id": "pqr",
                        "count": 4
                    }

We have a list of owners which is of type ArrayList<String>:

List<String> listOfOwners = ["abc","xyz","pqr"];

I want to collect all these things and want to create a result like below:

result:[
    {"owner": "abc",
    "ownerPresence":{
    "configCount":1,
    "websiteCount":2
    },
    {"owner": "xyz",
    "ownerPresence":{
    "configCount":1,
    "websiteCount":3
    },
    {"owner": "pqr",
    "ownerPresence":{
    "configCount":1,
    "websiteCount":4
    }]

I am not sure how I can do this in Java 8.

CodePudding user response:

  1. Remap the initial lists of maps into Map<String, Integer>:
static Map<String, Integer> convert(List<Map<String, Object>> list) {
    return list
        .stream()
        .collect(Collectors.toMap(
            m -> (String) m.get("web_id"),
            m -> (Integer) m.get("count")
        ));
}

List<Map<String, Object>> configs  = fetchConfigsCount();
List<Map<String, Object>> websites = fetchWebsitesCount();

Map<String, Integer> configMap  = convert(configs);
Map<String, Integer> websiteMap = convert(websites);
  1. Create a POJO to represent a list entry:
class Pojo {
    String owner;
    Map<String, Integer> ownerPresence;
    // boilerplate: constructor(s), getters/setters
}
  1. Stream the list of owners, and build a map:
List<String> listOfOwners = Arrays.asList("abc","xyz","pqr");

List<Pojo> result = listOfOwners
    .stream()
    .map(owner -> new Pojo(
        owner,
        Map.of(
            "configCount",  configMap.get(owner),
            "websiteCount", websiteMap.get(owner)
        )
    ))
    .collect(Collectors.toList());

CodePudding user response:

Here is one way to do it.

  • first, just remap the counts to a Map<String,List<Integer>>
  • then simply iterate over than map, building the final map and list.
Map<String, List<Integer>> map = Stream
        .concat(configCount.stream(), webCount.stream())
        .collect(Collectors.groupingBy(
                mp -> (String) mp.get("web_id"),
                Collectors.mapping(
                        mp -> (Integer) mp.get("count"),
                        Collectors.toList())));


}

The above creates the following where the first List value is the config count and the second is the website count.

pqr=[1, 4]
abc=[1, 2]
xyz=[1, 3]

Now instantiate a final List to hold all the maps and finish up.

List<Map<String, Object>> result = new ArrayList<>();

for (Entry<String, List<Integer>> e : map.entrySet()) {
    Map<String, Object> tempMap = new HashMap<>();
    tempMap.put("owner", e.getKey());
    tempMap.put("ownerPresence",
            new HashMap<>(Map.of("configCount",
                    e.getValue().get(0), "webSiteCount",
                    e.getValue().get(1))));
    result.add(tempMap);
}

result.forEach(mp -> mp.entrySet()
          .forEach(e -> System.out.println(e.getKey()   ":"   e.getValue())));

prints

owner:pqr
ownerPresence:{webSiteCount=4, configCount=1}
owner:abc
ownerPresence:{webSiteCount=2, configCount=1}
owner:xyz
ownerPresence:{webSiteCount=3, configCount=1}
  • Related