Java中如何移除两个ArrayList中的多属性重复对象
解决两个ArrayList中重复Employee对象的移除方案
没问题,我来帮你搞定这个需求!要移除两个列表中所有属性完全一致的Employee重复对象,核心是先让Employee类正确实现对象相等的判断逻辑,再通过集合操作或Stream来过滤重复项。下面是分步实现方案:
第一步:重写Employee类的equals()和hashCode()方法
Java默认的equals()是比较对象的内存引用,我们需要改成对比empname、email、mobile三个属性是否完全相同。同时必须重写hashCode(),保证equals返回true的两个对象,hashCode值也相同(这是HashSet、Stream distinct()等去重逻辑的基础)。
示例代码:
import java.util.Objects; public class Employee { private String empname; private String email; private String mobile; // 构造器 public Employee() {} // Getter和Setter方法 public String getEmpname() { return empname; } public void setEmpname(String empname) { this.empname = empname; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getMobile() { return mobile; } public void setMobile(String mobile) { this.mobile = mobile; } @Override public boolean equals(Object o) { if (this == o) return true; // 同一对象直接返回true if (o == null || getClass() != o.getClass()) return false; // 类型不同或为空返回false Employee employee = (Employee) o; // 对比三个属性,用Objects.equals避免空指针 return Objects.equals(empname, employee.empname) && Objects.equals(email, employee.email) && Objects.equals(mobile, employee.mobile); } @Override public int hashCode() { // 用三个属性生成hash值 return Objects.hash(empname, email, mobile); } }
如果是Java 7及更早版本(没有Objects类),可以手动实现:
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Employee employee = (Employee) o; // 手动处理空值判断 if (empname == null ? employee.empname != null : !empname.equals(employee.empname)) return false; if (email == null ? employee.email != null : !email.equals(employee.email)) return false; return mobile == null ? employee.mobile == null : mobile.equals(employee.mobile); } @Override public int hashCode() { int result = empname != null ? empname.hashCode() : 0; result = 31 * result + (email != null ? email.hashCode() : 0); result = 31 * result + (mobile != null ? mobile.hashCode() : 0); return result; }
第二步:选择合适的去重实现方式
方案1:用HashSet自动去重(高效,推荐)
HashSet会自动过滤重复元素,我们只需把两个列表的元素都加入,再转回ArrayList即可。如果需要保留元素的插入顺序,用LinkedHashSet代替HashSet。
代码示例:
import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class Main { public static void main(String[] args) { // 初始化你的两个列表(示例代码) ArrayList<Employee> arrayList1 = new ArrayList<>(); ArrayList<Employee> arrayList2 = new ArrayList<>(); Employee e = new Employee(); e.setEmpname("chandu"); e.setEmail("chandu@gmail.com"); e.setMobile("9030128664"); arrayList1.add(e); Employee e1 = new Employee(); e1.setEmpname("ramesh"); e1.setEmail("ramesh@gmail.com"); e1.setMobile("9154618845"); arrayList2.add(e); arrayList2.add(e1); // 去重操作 Set<Employee> uniqueSet = new HashSet<>(); uniqueSet.addAll(arrayList1); uniqueSet.addAll(arrayList2); // 转回ArrayList(如果需要列表类型) List<Employee> uniqueList = new ArrayList<>(uniqueSet); // 现在uniqueList里就是去重后的所有Employee对象 } }
方案2:Java 8+ Stream API去重(灵活,保留顺序)
如果想保留元素的原有顺序(先arrayList1的元素,再arrayList2中不重复的元素),可以用Stream的distinct()方法:
import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class Main { public static void main(String[] args) { // 初始化arrayList1和arrayList2(同上) // 合并两个流并去重 List<Employee> uniqueList = Stream.concat(arrayList1.stream(), arrayList2.stream()) .distinct() .collect(Collectors.toList()); } }
方案3:手动遍历过滤(适合理解底层逻辑)
如果不想用集合类的自动去重,也可以手动遍历判断,把不重复的元素加入新列表:
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) { // 初始化arrayList1和arrayList2(同上) List<Employee> uniqueList = new ArrayList<>(); // 先加入第一个列表的所有元素 uniqueList.addAll(arrayList1); // 遍历第二个列表,只添加不在uniqueList中的元素 for (Employee emp : arrayList2) { if (!uniqueList.contains(emp)) { uniqueList.add(emp); } } } }
注意事项
- 确保Employee的三个属性是不可变的,或者后续不会修改。如果修改了已加入集合的Employee对象的属性,会导致hashCode变化,集合无法正确识别重复元素。
- 所有去重逻辑都依赖我们重写的equals()和hashCode(),如果这两个方法写得不对,去重会失效。
内容的提问来源于stack exchange,提问作者user3291914
相关产品推荐
相关产品推荐

