在项目中某个请求的参数采用了较为复杂的规则拼接而成,在服务器端查询时需要将其解析成符合要求的MapList组合的格式。一开始自己采用的是传统的遍历方式实现,后续发现用Java8中引入的lambda表达式后代码变的更简洁、更优雅,故简单记录下。

问题描述

项目中有类似如下的字符串输入参数

1
010$$fengtai,010$$chaoyang,010$$haidain,027$$wuchang,027$$hongshan,027$$caidan,021$$changnin,021$$xuhui,020$$tianhe

调用方期望将输入参数转化为如下格式(即首先根据,进行分割,然后在根据$$进行进一步的拆分,最终的结果是按照$$前面的数据为key,$$后面的数据分别放入同一个数组中,最终结果以Map<String, List<String>>的格式返回)。

1
{027=[wuchang, hongshan, caidan], 020=[tianhe], 010=[fengtai, chaoyang, haidain], 021=[changnin, xuhui]}

传统方式

最开始由于需要尽快部署调试,自己才用的是传统的遍历方式,此种方式编码起来很简单,具备简单的Java基础即可实现。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
public 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;
}

基于Lambda实现

Stack Overflow上咨询后,发现用lambda实现更简洁,只用一行代码就能搞定!

1
2
3
4
5
6
7
public Map<String, List<String>> parseByLambda(String data) {
    Map<String, List<String>> resultMap = Arrays.stream(data.split(","))
        .map(s -> s.split("\\$\\$"))
        .collect(Collectors.groupingBy(s -> s[0],
                                       Collectors.mapping(s -> s[1], Collectors.toList())));
    return resultMap;
}

上述代码的核心是采用Java8中引入的Collectors类,采用其中的groupingBymapping方法实现,而自己用的最多的只是toListtoMap,基本功有待加强!