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

如何移除ArrayList<Couple>中人员顺序互换的重复对象?

解决ArrayList中Couple对象的互换重复问题

嘿,这个场景很典型——要移除那些只是两个人顺序互换的重复Couple对象对吧?核心就是得先明确「什么样的Couple算重复」:只要两个Couple包含的是同一对人,不管顺序如何,就视为重复。下面给你几个实用的解决方案,按需选择:

方案一:重写Couple的equals和hashCode(推荐)

这是最符合Java规范的做法,一旦你定义了Couple的相等规则,后续不管是用Set去重还是其他集合操作,都能自动识别重复对象。

首先修改你的Couple类,让它认为(A,B)和(B,A)是相等的:

import java.util.Objects;

class Couple {
    private String person1;
    private String person2;

    public Couple(String person1, String person2) {
        this.person1 = person1;
        this.person2 = person2;
    }

    // 添加上getter方法,方便后续操作
    public String getPerson1() {
        return person1;
    }

    public String getPerson2() {
        return person2;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true; // 同一对象直接返回相等
        if (o == null || getClass() != o.getClass()) return false; // 类型不同或null不相等
        Couple otherCouple = (Couple) o;
        // 两种相等情况:顺序完全一致,或者顺序互换
        return (Objects.equals(person1, otherCouple.person1) && Objects.equals(person2, otherCouple.person2))
                || (Objects.equals(person1, otherCouple.person2) && Objects.equals(person2, otherCouple.person1));
    }

    @Override
    public int hashCode() {
        // 按字典序排序两人名字后计算hash,确保(A,B)和(B,A)的hash值相同
        String first = person1.compareTo(person2) < 0 ? person1 : person2;
        String second = person1.compareTo(person2) < 0 ? person2 : person1;
        return Objects.hash(first, second);
    }
}

然后去重就非常简单了,利用HashSet自动去重的特性:

// 将原列表转成Set自动去重,再转回ArrayList
Set<Couple> uniqueCoupleSet = new HashSet<>(relationshipList);
relationshipList = new ArrayList<>(uniqueCoupleSet);

优点:一次定义规则,终身受益,后续任何涉及Couple相等判断的场景都能复用,代码简洁规范。

方案二:不修改Couple类,自定义标识去重

如果你没办法修改Couple类(比如它是第三方库的类),可以通过生成唯一标识来判断重复:

List<Couple> uniqueRelationshipList = new ArrayList<>();
Set<String> seenCoupleKeys = new HashSet<>();

for (Couple couple : relationshipList) {
    // 生成唯一键:把两人名字按字典序拼接,确保(A,B)和(B,A)生成同一个键
    String coupleKey = couple.getPerson1().compareTo(couple.getPerson2()) < 0
            ? couple.getPerson1() + "-" + couple.getPerson2()
            : couple.getPerson2() + "-" + couple.getPerson1();
    
    // 如果这个键没出现过,就保留当前Couple并记录键
    if (!seenCoupleKeys.contains(coupleKey)) {
        seenCoupleKeys.add(coupleKey);
        uniqueRelationshipList.add(couple);
    }
}

// 替换原列表为去重后的列表
relationshipList = uniqueRelationshipList;

优点:无需修改原类,灵活度高;缺点是需要额外维护一个Set来记录已处理的情侣对。

方案三:用Stream API简化去重(Java 8+)

如果喜欢更简洁的流式写法,可以结合Stream和Set来实现,逻辑和方案二一致:

import java.util.stream.Collectors;
import java.util.HashSet;
import java.util.Set;

Set<String> seenKeys = new HashSet<>();
List<Couple> uniqueList = relationshipList.stream()
        .filter(couple -> {
            String key = couple.getPerson1().compareTo(couple.getPerson2()) < 0
                    ? couple.getPerson1() + "-" + couple.getPerson2()
                    : couple.getPerson2() + "-" + couple.getPerson1();
            return seenKeys.add(key); // add方法返回true表示键不存在,会保留当前元素;反之过滤掉
        })
        .collect(Collectors.toList());

relationshipList = uniqueList;

优点:代码紧凑,适合Java 8及以上版本,可读性也不错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:47:37