【面试复盘】有了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判断两个对象是否相等 既保证了正确性 又提高了性能

相关推荐
01_ice1 分钟前
Java多态
java·开发语言
飞翔中文网3 分钟前
读RESTful有感,关于Java接口设计规范的说明
java·restful·设计规范
Byron__9 分钟前
Spring核心面试知识点(IoC/Bean生命周期/AOP/事务)
java·spring·面试
AI人工智能+电脑小能手17 分钟前
【大白话说Java面试题 第78题】【Mysql篇】第8题:解释下最左前缀原则?
java·开发语言·数据库·mysql·面试
掘金者阿豪32 分钟前
一个 DISTINCT,让我在上线前多盯了三天,最后发现数据库自己就能处理
后端
一起逃去看海吧38 分钟前
对接LangSmith
java·前端·数据库
wyhwust38 分钟前
web应用技术-第一次课后作业
java·前端·数据库
java1234_小锋41 分钟前
什么是 RAG(检索增强生成)?请简述 Spring AI 实现 RAG 的完整流程,包括涉及的核心组件。
java·人工智能·spring·rag
砍材农夫1 小时前
物联网 基于netty核心实战-心跳保活机制
java·后端·物联网·struts·servlet·netty
小江的记录本1 小时前
【JVM虚拟机】垃圾回收GC:垃圾判定算法:引用计数法、可达性分析算法(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·算法·spring·面试