如何移除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
相关产品推荐
相关产品推荐

