Home > Blockchain >  How to group and map string via lambda
How to group and map string via lambda

Time:11-15

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