You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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;
    }
}

关键步骤说明

  1. 展开一对多关联:使用flatMap将每个员工拆分为多个<城市, 员工>的键值对,解决一个员工对应多个地址的映射问题,让每个地址都能关联到所属员工。
  2. 分组收集结果:通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 10:50:30