equals()和hashCode()的区别和联系

==

  1. 基本数据类型:比较的是他们的值。
  2. 引用数据类型:比较的就是地址值是否相同

equals

 public boolean equals(Object obj) {
        return (this == obj);
    }

Object类中定义了一个equals的方法,通过源码我们可以看到,其实它本质上还是==,通常我们需要重写equals(),使它比较对象内容是否相等。例如:String、Integer、Date等类就重写了equals()。

hashCode

  1. hashCode() 的作用是获取哈希码,也称为散列码
  2. 同一个对象调用超过一次时,hashCode方法必须返回相同的哈希值,前提是不修改在对象的对等比较中使用的信息。
  3. 不同的对象调用hashCode方法必须产生不同的哈希值。
  4. 哈希码的作用是确定该对象在哈希表中的索引位置。

hashCode() 和 equals() 有什么关系?

在不会创建“类对应的散列表的情况下”
该类的“hashCode() 和 equals() ”没有半毛钱关系!
equals() 用来比较该类的两个对象是否相等,而hashCode() 则根本没有任何作用。
会创建“类对应的散列表的情况下”

会创建类对应的散列表”是指:在 HashSet, HashTable, HashMap等这些本质是散列表的数据结构中,用到该类。

该类的“hashCode() 和 equals() ”是有关系的:

  1. 如果两个对象相等,那么它们的hashCode()值一定相同。
  2. 如果两个对象hashCode()相等,它们并不一定相等。因为在散列表中,hashCode()相等,即两个键值对的哈希值相等。然而哈希值相等,并不一定能得出键值对相等,此时就出现所谓的哈希冲突场景。

在该情况下,为什么重写了equals()一定要重写hashCode() 。

  1. 重写了equals()使拥有相同内容的不同对象,判断为同一个对象。
  2. 没有重写hashCode(),它认为拥有相同内容的对象是不同的对象,返回不同的哈希值。这就出现了同一个对象调用hashCode()返回不同的哈希值。
  3. 而HashSet, HashTable, HashMap等是先通过hashCode方法判断,哈希值不同认为是不同的对象,哈希值相同再调用equals()判断对象是否是同一个对象。
  4. 这就有可能在HashSet, HashTable, HashMap等 中有重复元素出现。其根本原因是:equals认为拥有相同内容的对象是同一个对象,而hashCode认为拥有相同内容的对象不是同一个对象。
  5. 所以我们还需要重写hashCode(),使hashCode()判断拥有相同内容的对象为同一个对象。

举例:下⾯的代码中,新建了两个等价的对象,并将它们添加到 HashSet 中。我们希望将这两个对象当成⼀样 的,只在集合中添加⼀个对象。但是 EqualExample 没有实现 hashCode() ⽅法,因此这两个对象的哈希值是不同的,最终导致集合添加了两个等价的对象。

EqualExample e1 = new EqualExample(1, 1, 1);
EqualExample e2 = new EqualExample(1, 1, 1);
System.out.println(e1.equals(e2)); // true
HashSet<EqualExample> set = new HashSet<>();
set.add(e1);
set.add(e2);
System.out.println(set.size()); // 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值