【面试复盘】有了equals为什么还要hashcode

前言

早上在面一家公司的时候 被问到有了equals为什么还要hashcode方法 本来是一个比较简单的问题 但是在讲完各自的作用后想讲讲自己的理解的时候突然卡壳 所以写一篇文章来梳理一下这个逻辑

分析

首先 equals和hashcode方法通常是成对出现的 在使用一些哈希结构的时候非常重要 比如HashMap HashTable等

  • equals方法 用于判断两个对象是否相等 我们可以重写equals方法 来决定两个对象相等的逻辑 比如在String类中 重写了equals方法 认为两个字符串相等 那就是相等的
  • hashcode方法 返回一个整数哈希码 从而快速定位存储位置 提高查询效率

理解完他们的作用后 我们来看一下HashMap的源码 我这里展示了put的部分源码

ini 复制代码
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
               boolean evict) {
    Node<K,V>[] tab; Node<K,V> p; int n, i;
    if ((tab = table) == null || (n = tab.length) == 0)
        n = (tab = resize()).length;
    if ((p = tab[i = (n - 1) & hash]) == null)
        tab[i] = newNode(hash, key, value, null);
    else {
        Node<K,V> e; K k;
       //如果哈希值相等 
        if (p.hash == hash &&
        //判断地址相同 或者 逻辑相同
            ((k = p.key) == key || (key != null && key.equals(k))))
            e = p;
        else if (p instanceof TreeNode)
            e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
        else {
            for (int binCount = 0; ; ++binCount) {
                if ((e = p.next) == null) {
                    p.next = newNode(hash, key, value, null);
                    if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                        treeifyBin(tab, hash);
                    break;
                }
              //   //如果哈希值相等 
                if (e.hash == hash &&
                //地址相同 或者 逻辑相同
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    break;

通过查看源码可以发现 hashcode的计算值

  • 用于寻找插入位置 并且用于快速判断两个元素是否相同
  • 如果相同再判断两个元素是否是同一个元素

总结

总的来说

分为两方面 提高效率 保证对象唯一性

hashcode提供了一种快速计算对象哈希值的方式 可以快速定位到元素应该存放在哪 提高了查询和存放效率

另外一方面 和equals做协同 保证数据的一致性和完整性 通过HashMap的源码也可以看到 他会缓存已有键值对的哈希码 用于快速判断元素是否存在 如果两个对象的hashcode值不同 那么就不可能是同一个对象 如果相同 再通过equals判断两个对象是否相等 既保证了正确性 又提高了性能

相关推荐
一灯架构7 小时前
90%的人答错!一文带你彻底搞懂ArrayList
java·后端
Y4090018 小时前
【多线程】线程安全(1)
java·开发语言·jvm
布局呆星8 小时前
SpringBoot 基础入门
java·spring boot·spring
mldong9 小时前
Python开发者狂喜!200+课时FastAPI全栈实战合集,10大模块持续更新中🔥
后端
风吹迎面入袖凉9 小时前
【Redis】Redisson的可重入锁原理
java·redis
w6100104669 小时前
cka-2026-ConfigMap
java·linux·cka·configmap
GreenTea9 小时前
从 Claw-Code 看 AI 驱动的大型项目开发:2 人 + 10 个自治 Agent 如何产出 48K 行 Rust 代码
前端·人工智能·后端
语戚10 小时前
力扣 968. 监控二叉树 —— 贪心 & 树形 DP 双解法递归 + 非递归全解(Java 实现)
java·算法·leetcode·贪心算法·动态规划·力扣·
quxuexi10 小时前
网络通信安全与可靠传输:从加密到认证,从状态码到可靠传输
java·安全·web