面试1:HashMap为什么要同时重写hashCode()和equals()方法

先放结论: 通过重写的hashcode 直接定位到key 的位置 , 根据重写的equals 保证唯一性。

 hashCode()方法主要用来定位元素在数组中的下标位置;

equals()方法主要是在发生hash冲突时,遍历链表,挨个比较元素时,判断两个元素是否相等。

重写hashCode():

保证hashmap键的唯一性

hashmap 初始化的时候是一个table 数组, 默认是16大小 , 然后如果有了hash冲突每一个键值对的下方会有一个链表进行hash冲突的解决方式 。

假如只重写hashcode , 不重写equals :

put ("a" ,"123") ; ---> 存这个的时候调用key 的hashCode , 因为Object的hashcode返回的是内存地址 ,如果不重写hashcode , 那么同样的一个键值对 , 唯一性得不到保证 。

假设上方put ("a" ,"123") ; put成功 ,如果这个时候继续调用一次put ("a" ,"123") ;那么如果没有重写hashCode , 则此时两者都用的Object的hashcode去返回内存地址 , 两者hashcode比较肯定是不同的 ,原因在于不是同一个对象 。

则存储的情况可能是这样的 : 假设table 长度为 6

1 2 3 4 5 6
(a,123)   (a, 123)      

 

重写equals():

object 的equals 是 比较是否为同一个对象 , 即内存地址是否一样 。

此时我还是 put ("a" ,"123") ; 接着我在put ("b" ,"123") ;两次put 元素 ,假设这两次put的时机刚好key的hash 命中了 ,即发生了hash冲突 , 那么按照hashmap的解决方式 , 用了链表进行冲突位置的连接 , 存储情况如下:

1 2 3 4 5 6
(a, 123)          
(b, 123)          

 

那么执行过程是 对 a 进行hashcode 的判断 ,知道是在1号位置 , 那么去1号位置 , 发现有两个元素,

一个是(a,123)  、一个是(b,123) , 那我应该怎么判断呢 ? 肯定是用equals 进行判断 。

 

什么时候需要重写hashcode和equals方法?

在HashMap中存放自定义的键时,就需要重写自定义对象的hashcode和equals方法

 

如何重写hashcode和equals方法

复制代码
class Key {
    private Integer id;

    public Integer getId() {
        return id;
    }

    public Key(Integer id) {
        this.id = id;
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !(obj instanceof Key)) {  //instanceof 判断左边最想是否为其右边类的实例
            return false;
        } else {
            return this.getId().equals(((Key) obj).getId());  //比较两个对象的id值是否相同
        }
    }
}

public class WithoutHashCode {
    public static void main(String[] args) {
        Key k1 = new Key(1);
        Key k2 = new Key(1);

        HashMap<Key, String> hashMap = new HashMap<>();
        hashMap.put(k1, "Key with id is 1");
        System.out.println(hashMap.get(k2));
    }
}
复制代码

 

 

 转载bilibili讲解视频:https://www.bilibili.com/video/BV1u44y1K7GA?spm_id_from=333.337.search-card.all.click

 

posted @   草莓小甜心  阅读(286)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
点击右上角即可分享
微信分享提示