如何将List <person>转换为Map <string,list <employee >>

时间:2018-08-20 18:06:28

标签: java-8 java-stream

这是用Java7编写的一段代码,我想使用Streams和Lambdas转换为Java8。

public static Map<String, List<Employee>> getEmployees(List<Person> personList) {
        Map<String, List<Employee>> result = new HashMap<>();
        for (Person person : personList) {
            String[] perArr = person.getName().split("-");
            List<Employee> employeeList = result.get(perArr[0]);
            if (employeeList == null) {
                employeeList = new ArrayList<>();
            }
            employeeList.add(new Employee(person.getPersonId(), perArr[1]));
            result.put(perArr[0], employeeList);
        }

        return result;

    }

2 个答案:

答案 0 :(得分:2)

好吧,我要说的有点亲密,问题在于您实际上需要传递到流管道的下一个阶段3件事:第一个令牌和第二个令牌(来自split("-"))以及{{ 1}};我在这里使用了person::getPersonId,并为此进行了一些强制转换(例如,您可以使用List,我听说过apache拥有它):

Triple

答案 1 :(得分:2)

改善循环的一种直接方法是使用Map.computeIfAbsent管理新地图条目的创建:

for (Person person : personList) {
    String[] perArr = person.getName().split("-");
    List<Employee> employeeList = result.computeIfAbsent(perArr[0], x -> new ArrayList<>());
    employeeList.add(new Employee(person.getPersonId(), perArr[1]));
}

使用流执行此操作有些尴尬,因为您无法方便地携带中间计算的结果,因此您必须使事务与中间对象复杂化,或者只是再次拆分字符串:

import static java.util.stream.Collectors.*;

personList.stream()
    .collect(groupingBy(
                p -> p.getName().split("-")[0],
                mapping(
                    p -> new Employee(p.getPersonId(), p.getName().split("-")[1]),
                    toList()
                )
    ));