I have a string as below:
String data = "010$$fengtai,010$$chaoyang,010$$haidain,027$$wuchang,027$$hongshan,027$$caidan,021$$changnin,021$$xuhui,020$$tianhe";
And I want to convert it into Map<String, List> like below(first split by ,
and split by $$
,value before $$
is key need to be group,and value after $$
needs to put inside a list):
{027=[wuchang, hongshan, caidan], 020=[tianhe], 010=[fengtai, chaoyang, haidain], 021=[changnin, xuhui]}
I have use a traditional way to do it
private Map<String, List<String>> parseParametersByIterate(String sensors) {
List<String[]> dataList = Arrays.stream(sensors.split(",")).map(s -> s.split("\\$\\$")).collect(Collectors.toList());
Map<String, List<String>> resultMap = new HashMap<>();
for (String[] d : dataList) {
List<String> list = resultMap.get(d[0]);
if (list == null) {
list = new ArrayList<>();
list.add(d[1]);
resultMap.put(d[0], list);
} else {
list.add(d[1]);
}
}
return resultMap;
}
But it seems more complicated and not very elegant,thus I want to use java8 lambda,such as grouping
and map
to meke it one-liner
What I have tried so far is below
Map<String, List<String>> result =
Arrays.stream(data.split(",")).collect(Collectors.groupingBy(s -> s.split("\\$\\$")[0]))
But the output is not what I want to have,can anyone help me to do it? Thanks in advance!
CodePudding user response:
You simply need to map the values of the mapping. You can do that by specifying a second argument to Collectors.groupingBy
:
Collectors.groupingBy(s -> s.split("\\$\\$")[0], Collectors.mapping(s -> s.split("\\$\\$")[1],Collectors.toList()))
Instead of then splitting twice, you can split first and group afterwards:
Arrays.stream(data.split(",")).map(s -> s.split("\\$\\$")).collect(Collectors.groupingBy(s -> s[0], Collectors.mapping(s -> s[1],Collectors.toList())));
Which now outputs
{027=[wuchang, hongshan, caidan], 020=[tianhe], 021=[changnin, xuhui], 010=[fengtai, chaoyang, haidain]}