重写对象的hashcode和equals方法实现对List对象集合中对象元素的去重复

本文深入探讨了Java中集合去重的原理与实践,重点讲解了如何通过重写hashCode和equals方法实现对象类型的去重,提供了详细的代码示例。

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

1.我们大家都知道,set集合的特点就是没有重复的元素。如果集合中的数据类型是基本数据类型,可以直接将list集合转换成set,就会自动去除重复的元素,这个就相对比较简单。

public class Test {

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(11);
        list.add(12);
        list.add(13);
        list.add(14);
        list.add(15);
        list.add(11);
        System.out.println(list);

        Set set = new HashSet();
        List newList = new ArrayList();
        set.addAll(list);
        newList.addAll(set);
        System.out.println(newList);

    }

}

输出结果为:

2.但是当list集合中存储的类型是对象类型的时候,而我们又想把对象中某一个或多个属性值相同的对象进行去重,那么这种方式就不行了

3.我们要怎么做呢,我们如果还想用set方法去重那么就可以重写list对象中的hashCode和equals方法来实现list转化为Set时相同属性值的对象去重

4.例如:我们想对活动商品ActivityItem对象中,商品skuCode相同(销售单元无所谓)的对象去重复,那么就可以重写ActivityItem对象的hashCode和equals方法来实现

  @Override
    public int hashCode() {
        /**
         *  首先判断该对象的hashCode值是否相同
         *  如果相同则再进一步equals方法比较是否相同,如果equals方法也相同则可以认为是同意对象
         *  如果hashCode不相同则肯定不是同一个对象,那么就没必要比较equals了
         *  所以我们可以利用重新对象的hashCode和equals方法来实现对自定义的对象去重
         *
         *  这也同样证明了一点:两个对象equals相等,则它们的hashcode必须相等,反之则不一定。
         *  两个对象相等那么他们的hashCode和equals一定相等,但如果只有hashcode那么两个对象不一定相等
         */

        return Objects.hash(super.hashCode(), skuCode);
    }
 public static void main(String[] args) {
        List<ActivityItem> items = new ArrayList<>();
        ActivityItem item1 = new ActivityItem();
        item1.setSkuCode("111");
        item1.setUnitCode("a");
        ActivityItem item2 = new ActivityItem();
        item2.setSkuCode("222");
        item2.setUnitCode("b");
        ActivityItem item3 = new ActivityItem();
        item3.setSkuCode("111");
        item3.setUnitCode("c");
        items.add(item1);
        items.add(item2);
        items.add(item3);
        System.out.println("list:"+items.toString());
        Set<ActivityItem> hashSet = new HashSet<>();
        hashSet.addAll(items);
        items.clear();
        items.addAll(hashSet);
        System.out.println("list22:"+items.toString());
    }

输出结果:

list:[ActivityItem(skuCode=111,  unitCode=a), ActivityItem(skuCode=222,  unitCode=b), ActivityItem(skuCode=111 unitCode=c, unitName=null)]
list222:[ActivityItem(skuCode=111,  unitCode=a), ActivityItem(skuCode=222,  unitCode=b))]

5.下面来说明这样做为什么可以对对象元素进行去重

HashSet的add()方法,首先会使用当前集合中的每一个元素和新添加的元素进行hash值比较

如果hash值不一样,那么肯定不是相同的对象,则直接添加新的元素;

如果hash值一样,那么就比较地址值或者使用equals方法进行比较

而按照我们上述例子中重写的方法来看,我们期望的是想要把对象中skuCode相同的元素做相同对象进行去重,所以我们要使用了Objects.hash(super.hashCode(), skuCode);先对skucode求hash值看是否是同一个对象,如果不相等肯定不是同一个对象,如果相等那么再比较equals方法中Objects.equals(skuCode, that.skuCode);新加元素的属性值和当前集合中元素的属性值是否相同,如果equals结果相同那么就是同一个对象可以去重,如果equals结果不相同那么就不是同一个对象。

所以: 对象相等则hashCode一定相等;hashCode相等对象未必相等。

相等的对象必须具有相等的哈希码。每当equals方法被覆写,通常需要重写hashCode方法从而
保持对象行为的一致性

6.但是为什么hashCode相同的两个对象不一定相等呢?

当我们看hashCode方法的源码是发现

比较hashCode是否相同时,是拿对象的每个属性进行hash求职然后相加,所以如果两个不同的对象如果属性值相同那么这两个对象的hash值也可能相等,但是对象却不是同一个对象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值