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

如何基于手机号移除ArrayList中重复的PhoneContactsModel对象?

问题排查与解决方案

咱们先拆解你遇到的两个核心问题:TreeSet去重失效和HashSet未生效,逐个分析原因并给出可落地的修复方案。

1. TreeSet去重失效的根源:Comparator实现不符合规范

你自定义的Comparator存在逻辑漏洞:TreeSet依赖Comparator的返回值判断元素是否相等,规范要求如果a.compare(b) == 0,必须满足b.compare(a) == 0;如果a.compare(b) > 0,则b.compare(a) < 0。

但你的实现里,只要手机号不相等就返回1,这会让TreeSet误以为A和B、B和A都是不同元素,导致重复项无法被识别。

修复后的TreeSet去重代码

可以用Java 8的Comparator.comparing简化实现,同时保证逻辑合规:

public ArrayList<PhoneContactsModel> removeDuplicates(ArrayList<PhoneContactsModel> list) {
    // 按手机号忽略大小写比较,同时处理null场景
    Set<PhoneContactsModel> set = new TreeSet<>(Comparator.comparing(
        PhoneContactsModel::getContactNumber,
        (s1, s2) -> {
            if (s1 == null && s2 == null) return 0;
            if (s1 == null) return -1;
            if (s2 == null) return 1;
            return s1.compareToIgnoreCase(s2);
        }
    ));
    set.addAll(list);
    return new ArrayList<>(set);
}

2. HashSet去重未生效的可能原因及修复

你已经重写了equals和hashCode,按道理HashSet应该能正常去重,没生效大概率是这几个问题:

  • 手机号格式不一致:比如有的带+86前缀、有的带空格/连字符,导致equals判断不相等
  • equals方法未处理null:如果某个对象的contactNumber为null,直接调用equals会抛空指针,也无法正确比较null场景
  • 代码执行逻辑问题:比如没有把HashSet的结果重新赋值给目标列表

第一步:完善equals和hashCode方法

先补上null处理,同时支持忽略大小写(如果业务需要):

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (!(o instanceof PhoneContactsModel)) return false;
    PhoneContactsModel that = (PhoneContactsModel) o;
    // 处理null场景,同时忽略大小写比较手机号
    if (contactNumber == null) {
        return that.contactNumber == null;
    }
    return contactNumber.equalsIgnoreCase(that.contactNumber);
}

@Override
public int hashCode() {
    // 保证忽略大小写的手机号hashCode一致,同时处理null
    return contactNumber == null ? 0 : contactNumber.toLowerCase().hashCode();
}

第二步:HashSet去重代码

public ArrayList<PhoneContactsModel> removeDuplicates(ArrayList<PhoneContactsModel> list) {
    Set<PhoneContactsModel> set = new HashSet<>(list);
    return new ArrayList<>(set);
}

额外优化:保留元素插入顺序

如果你的需求是保留列表中第一个出现的重复元素,而不是TreeSet排序后的结果,推荐用LinkedHashSet——它既能去重,又能严格保持元素的插入顺序:

public ArrayList<PhoneContactsModel> removeDuplicates(ArrayList<PhoneContactsModel> list) {
    Set<PhoneContactsModel> set = new LinkedHashSet<>(list);
    return new ArrayList<>(set);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:23:05