如何从存储Student对象的ArrayList中移除重复元素
ArrayList中自定义Student对象去重的实现方案
核心前提提醒
如果直接把Student对象丢进HashSet或者用Stream的distinct()方法,大概率会去重失败——因为Java默认的判重逻辑是比对对象的内存地址,完全认不出两个字段一模一样的Student是重复元素。必须先在Student类中,按照业务定义的重复判断规则(即id、name、birthdate三个字段完全一致就算重复)重写equals()和hashCode()方法,所有后续的去重操作才能生效。
常用实现方式
1. 借助LinkedHashSet去重(保留原列表元素顺序)
LinkedHashSet既具备Set集合元素不重复的特性,又会按照元素插入的顺序存储,不会打乱原ArrayList的遍历顺序,是最常用的去重实现:
// 直接将原list传入LinkedHashSet完成去重,再转回ArrayList即可 List<Student> dedupedStudentList = new ArrayList<>(new LinkedHashSet<>(studentList));
2. Java 8+ Stream流去重
如果项目用的是Java 8及以上版本,可直接用Stream的distinct()方法完成去重,同样会保留原列表的元素顺序:
import java.util.stream.Collectors; List<Student> dedupedStudentList = studentList.stream() .distinct() .collect(Collectors.toList());
3. 手动遍历实现(无需修改Student类的判重方法)
如果不想改动Student类的equals()和hashCode()逻辑,可以手动遍历过程中按业务规则做去重判断。比如用临时集合存储已出现的学生唯一标识,碰到重复标识的元素就跳过:
- 如果去重规则为同id即重复,就把学生id作为临时Set的存储内容
- 如果去重规则为全字段匹配才算重复,就把
id+name+birthdate的拼接字符串作为临时Set的存储内容
示例代码:
// 用临时Set存已经遇到过的学生唯一标识 Set<String> seenMarks = new HashSet<>(); List<Student> dedupedStudentList = new ArrayList<>(); for (Student stu : studentList) { // 拼接需要匹配的字段作为判重标记 String mark = stu.getId() + "|" + stu.getName() + "|" + stu.getBirthdate(); // add方法返回true代表元素是第一次出现,就把它加入结果列表 if (seenMarks.add(mark)) { dedupedStudentList.add(stu); } }
针对示例列表的实际效果
你给出的studentList里,两条完全相同的Student{id=S101312, name='Alex Mike', birthdate=10/13/1998}会被判定为重复元素,去重后最终列表只会保留1条该学生的记录,加上另外两个不重复的学生条目,最终列表共3个元素,不会出现重复内容。
内容的提问来源于stack exchange,提问作者user15429804
相关产品推荐
相关产品推荐

