List利用HashSet去重不成功

本文深入探讨了在Java中使用HashSet进行List数据去重时遇到的问题,并提供了详细的解决方案。通过重写User类的equals和hashCode方法,实现了对含有重复POJO对象的List的有效去重。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于业务需求,需要进行List数据去重,list中存的是一个pojo,根据网上使用HashSet进行去重,发现去重失败。通过一下博文发现原因,引用一下,原文地址→Java中list去重(用set元素不重复性)

定义一个对象:


public class User{
 
   public User(String name, int age) {
       this.name = name;
       this.age = age;
   }
 
   String name;
     int age;
  //省略getter&setter
}

 测试数据:

ArrayList<User> arrayList = new ArrayList<>();
arrayList.add(new User("111",10));
arrayList.add(new User("111",10));
arrayList.add(new User("222",20));
arrayList.add(new User("111",10));
arrayList.add(new User("222",20));
arrayList.add(new User("333",30));
arrayList.add(new User("111",10));
arrayList.add(new User("111",10));
arrayList = new ArrayList<>(new HashSet<User>(arrayList));

输出结果:

arrayList [0] = 111 , 10
arrayList [1] = 111 , 10
arrayList [2] = 222 , 20
arrayList [3] = 111 , 10
arrayList [4] = 333 , 30
arrayList [5] = 111 , 10
arrayList [6] = 222 , 20
arrayList [7] = 111 , 10

 去重失败。

在User类中加入

   //hshset中使用equals和hascode方法进行对象比较

   @Override
   public boolean equals(Object o) {
       if(this == o){
           return true;
       }
       if(o == null){
           return false;
       }
 
       if(getClass() != o.getClass()){
           return false;
       }
       User user = (User) o;
       if(age != user.age){
           return false;
       }
       if(name == null){
           if(user.name !=null){
               return false;
           }
       }else{
           if(!name.equals(user.name)){
               return false;
           }
   @Override
   public int hashCode() {
       return 1;
   }

加入重写的equals和hashConde方法,测试成功;

hashCode()方法给对象返回一个hash code值。这个方法被用于hash tables,例如HashMap等。

它的性质是:

  • 在一个Java应用的执行期间,如果一个对象提供给equals做比较的信息没有被修改的话,该对象多次调用hashCode()方法,该方法必须始终如一返回同一个integer。
  • 如果两个对象根据equals(Object)方法是相等的,那么调用二者各自的hashCode()方法必须产生同一个integer结果。
  • 并不要求根据equals(java.lang.Object)方法不相等的两个对象,调用二者各自的hashCode()方法必须产生不同的integer结果。然而,程序员应该意识到对于不同的对象产生不同的integer结果,有可能会提高hash table的性能。

大量的实践表明,由Object类定义的hashCode()方法对于不同的对象返回不同的integer。因此在自定义对象中加入hashCode可以实现List利用HashSet去重

### 如何使用 `HashSet` Java 对象中的复项 在 Java 中,`HashSet` 实现了 `Set` 接口并提供了自动复元素的功能。由于 `HashSet` 底层依赖于 `HashMap` 来存储数据,在添加新元素时会依据该元素的哈希码决定其存放位置[^3]。 对于自定义对象而言,为了确保能够正确识别相同对象从而避免复,必须适当地写 `hashCode()` 和 `equals(Object obj)` 方法[^4]。这是因为 `HashSet` 判断两个对象是否相等的标准仅限于它们具有相同的哈希码,还需要这两个对象通过 `equals()` 方法返回 true 才能认为是同一个对象[^5]。 下面是一个简单的例子展示如何创建一个可变类,并为其提供合适的 `hashCode/equals` 实现以便可以在 `HashSet` 中正常工作: ```java import java.util.*; class Person { private final String name; private final int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Person)) return false; Person person = (Person) o; // 如果name和age都一样则视为同一对象 return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } } public class Main { public static void main(String[] args) { List<Person> peopleWithDuplicates = Arrays.asList( new Person("Alice", 30), new Person("Bob", 25), new Person("Alice", 30), // Duplicate entry new Person("Charlie", 28) ); Set<Person> uniquePeople = new HashSet<>(peopleWithDuplicates); System.out.println(uniquePeople.size()); // 输出应为3而是4 } } ``` 在这个例子中,即使列表中有多个表示同一个人的同实例(即拥有完全相同的属性),一旦这些实例被放入到 `HashSet` 后也只会保留一份副本。因此实现了的效果[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值