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.
CodePudding user response:
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]
CodePudding user response:
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.