如何使用Java 8 Stream按城市分组员工为Map<String, List<Employee>>
如何用Java Stream创建按城市分组的Map<String, List>
核心实现代码
假设你已将所有员工存入列表,可通过以下Stream操作完成分组:
import java.util.*; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { Employee emp1 = new Employee("emp1", "emp1"); Employee emp2 = new Employee("emp2", "emp2"); Address address1 = new Address("city1"); Address address2 = new Address("city2"); List<Address> list1 = new ArrayList<>(); list1.add(address1); List<Address> list2 = new ArrayList<>(); list2.add(address2); emp1.setAddressList(list1); emp2.setAddressList(list2); // 把员工统一存入列表 List<Employee> employees = Arrays.asList(emp1, emp2); // 按城市分组生成目标Map Map<String, List<Employee>> cityToEmployees = employees.stream() // 展开员工与地址的关联:每个地址对应所属员工 .flatMap(employee -> employee.getAddressList().stream() .map(address -> new AbstractMap.SimpleEntry<>(address.getCity(), employee))) // 按城市分组,收集对应员工列表 .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList()) )); // 测试输出分组结果 cityToEmployees.forEach((city, emps) -> System.out.println(city + ": " + emps)); } } // 补充Employee和Address类的必要结构(需包含对应getter) class Employee { private String id; private String name; private List<Address> addressList; public Employee(String id, String name) { this.id = id; this.name = name; } public List<Address> getAddressList() { return addressList; } public void setAddressList(List<Address> addressList) { this.addressList = addressList; } @Override public String toString() { return "Employee{id='" + id + "', name='" + name + "'}"; } } class Address { private String city; public Address(String city) { this.city = city; } public String getCity() { return city; } }
关键步骤说明
- 展开一对多关联:使用
flatMap将每个员工拆分为多个<城市, 员工>的键值对,解决一个员工对应多个地址的映射问题,让每个地址都能关联到所属员工。 - 分组收集结果:通过
Collectors.groupingBy按城市(键值对的key)分组,再用Collectors.mapping提取员工对象并收集为列表,最终得到目标Map。
优化:避免同员工重复出现
如果存在一个员工拥有多个同一城市的地址,上述代码会将该员工重复加入对应城市的列表。若需去重,可在展开阶段先对员工的城市去重:
Map<String, List<Employee>> cityToEmployees = employees.stream() .flatMap(employee -> employee.getAddressList().stream() .map(Address::getCity) .distinct() // 对当前员工的城市去重,避免同一员工重复加入 .map(city -> new AbstractMap.SimpleEntry<>(city, employee))) .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList()) ));
内容的提问来源于stack exchange,提问作者arug977
相关产品推荐
相关产品推荐

