user15499060
user15499060

Reputation:

Grouping the Map Keys based on the part of the key in Java 8

I have a map which contains information as below:

"source.temp.temp1.issuer.value": "Hend",
"source.temp.temp2.issuer.value": "Ledge",
"source.temp.temp1.issuer.audence": "Legos1",
"source.temp.temp2.issuer.audence": "Legos2",
"source.temp.temp1.issuer.algp": "esc",
"source.temp.temp2.issuer.algp": "esc"

I need to do grouping based on the part of the key, i.e temp1, temp2, etc. Save them and make a list out of it. So the final result should be like this:

[
    {
        "source.temp.temp1.issuer.value": "Hend",
        "source.temp.temp1.issuer.audence": "Legos1",
        "source.temp.temp1.issuer.algp": "esc"
    },
    {
        "source.temp.temp2.issuer.value": "Ledge",
        "source.temp.temp2.issuer.audence": "Legos2",
        "source.temp.temp2.issuer.algp": "esc"
    },
    ...
]

The keys are of Object type.

Upvotes: 1

Views: 1545

Answers (2)

Prasath
Prasath

Reputation: 1284

You can follow this, added comments in every steps.

        List<Map<String, String>> groups = source.entrySet().stream() //take maps entryset stream
            .collect(Collectors.groupingBy(e->e.getKey().contains("temp1")?"tempKey1":"tempKey2")) //group based on your term/logic Result will be <newKey, List<Entry>>
            .values().stream() //Ignore newly created key take values alone into stream again => result stream of Entry
            .map(entryList-> {
                return entryList.stream().collect(Collectors.toMap(e->e.getKey(), e->e.getValue()));
            }) //Convert entry into Map
            .collect(Collectors.toList()); //collect stream of map into List of map
    System.out.println(groups);

In groupingBy you can change the login whatever you want. Currently I hardcoded with temp1 & temp2 alone.

Upvotes: 0

Alexander Ivanchenko
Alexander Ivanchenko

Reputation: 28988

With Stream API, you can do it by utilizing the collector Collectors.groupingBy().

The classifier function that needs to be passed as an argument will replace everything after "issue" with an empty string. By default, groupingBy() collects all elements mapped to the same key into a list.

Map<String, String> source =
         Map.of("source.temp.temp1.issuer.value", "Hend",
                "source.temp.temp2.issuer.value", "Ledge",
                "source.temp.temp1.issuer.audence", "Legos1",
                "source.temp.temp2.issuer.audence", "Legos2",
                "source.temp.temp1.issuer.algp", "esc",
                "source.temp.temp2.issuer.algp", "esc");

Map<Object, List<String>> result =
        source.keySet().stream()
              .collect(Collectors.groupingBy(str -> str.replaceAll("\\.issuer(.)*", "")));

result.entrySet().forEach(System.out::println);

Output

source.temp.temp2=[source.temp.temp2.issuer.value, source.temp.temp2.issuer.algp, source.temp.temp2.issuer.audence]
source.temp.temp1=[source.temp.temp1.issuer.algp, source.temp.temp1.issuer.audence, source.temp.temp1.issuer.value]

Upvotes: 2

Related Questions