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

如何按内部对象Address的street和city字段对List<Man>进行分组?

按Address的street和city分组List的实现方法

嘿,这个问题用Java的Stream API就能轻松解决!先给你梳理几种实用的方案,先假设你的两个类结构大概是这样(如果和你的实际类有出入,调整getter就行):

class Man {
    private String name;
    private Address address;

    // 构造器、toString等省略
    public Address getAddress() {
        return address;
    }
}

class Address {
    private String street;
    private String city;

    // 构造器、toString等省略
    public String getStreet() {
        return street;
    }
    public String getCity() {
        return city;
    }
}

方案1:自定义分组Key类(兼容所有Java版本)

因为要同时用street和city作为分组依据,我们可以自定义一个类来封装这两个字段,必须重写equals()和hashCode()方法——这是分组的关键,因为groupingBy底层用HashMap判断Key是否相同,完全依赖这两个方法。

import java.util.Objects;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class AddressKey {
    private final String street;
    private final String city;

    public AddressKey(String street, String city) {
        this.street = street;
        this.city = city;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AddressKey that = (AddressKey) o;
        return Objects.equals(street, that.street) && Objects.equals(city, that.city);
    }

    @Override
    public int hashCode() {
        return Objects.hash(street, city);
    }

    // 可选:重写toString,方便打印查看分组结果
    @Override
    public String toString() {
        return street + " | " + city;
    }
}

// 执行分组逻辑
public static void main(String[] args) {
    List<Man> manList = // 初始化你的Man集合
    Map<AddressKey, List<Man>> groupedMap = manList.stream()
        .collect(Collectors.groupingBy(man -> 
            new AddressKey(man.getAddress().getStreet(), man.getAddress().getCity())
        ));
}

方案2:用Java自带的SimpleEntry(无需自定义类)

如果不想额外写类,可以直接用AbstractMap.SimpleEntry,它已经帮我们实现了equals()和hashCode(),拿来当分组Key刚好合适:

import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 执行分组逻辑
public static void main(String[] args) {
    List<Man> manList = // 初始化你的Man集合
    Map<AbstractMap.SimpleEntry<String, String>, List<Man>> groupedMap = manList.stream()
        .collect(Collectors.groupingBy(man -> 
            new AbstractMap.SimpleEntry<>(man.getAddress().getStreet(), man.getAddress().getCity())
        ));
}

方案3:用Java 16+的Record(最简洁)

Java 16引入的Record可以自动生成equals()、hashCode()和toString(),代码会非常简洁清爽:

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// 定义一个Record作为分组Key
record AddressKey(String street, String city) {}

// 执行分组逻辑
public static void main(String[] args) {
    List<Man> manList = // 初始化你的Man集合
    Map<AddressKey, List<Man>> groupedMap = manList.stream()
        .collect(Collectors.groupingBy(man -> 
            new AddressKey(man.getAddress().getStreet(), man.getAddress().getCity())
        ));
}

关键注意点

不管用哪种方案,核心都是:分组的Key必须能正确标识“相同的street+city组合”,也就是必须保证两个Key的street和city都相同时,equals()返回true,hashCode()返回相同值——不然分组会把本该同组的元素分到不同组里,这点一定要注意哦!

内容的提问来源于stack exchange,提问作者Andrew Valevskiy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:48:49