为什么 String#equals 方法在做比较时没有使用 hashCode

news2024/10/5 23:29:36

一个疑问的引入

我之前出于优化常数项时间的考虑,想当然的认为 String#equals 会事先使用 hashCode 进行过滤

我想像中的算法是这样的

  1. 当两个 hashCode 不等时,直接返回 false(对 hash 而言,相同的输入会得到相同的输出)。此时就能避免后续的双指针比对(时间复杂度: O ( m i n ( n , m ) ) O(min(n, m)) O(min(n,m)))
  2. 当两个 hashCode 相等时,考虑 hash collision(不同的输入可能会得到相同的输出)。此时后面的比对就无法避免了

也就是以下的代码

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length && this.hashCode() == anotherString.hashCode()) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

但事实上确是

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

也就是我先前的设计思路有问题,但不妨参考一下 HashMap#getNode

final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
        if (first.hash == hash && // always check first node,显然这里是利用了 hashCode 进行过滤的
            ((k = first.key) == key || (key != null && key.equals(k))))
            return first;
        if ((e = first.next) != null) {
            if (first instanceof TreeNode)
                return ((TreeNode<K,V>)first).getTreeNode(hash, key);
            do {
                if (e.hash == hash &&
                    ((k = e.key) == key || (key != null && key.equals(k))))
                    return e;
            } while ((e = e.next) != null);
        }
    }
    return null;
}

也就是说之前构思出来的算法应该是没有问题的,于是就有了一个疑问:为什么 String#equals 不使用 hashCode 进行第一次过滤?

一个我认为靠谱的答案

stackoverflow 高分答案

  1. String 的 hashCode 是延迟计算的,当字符串很长时进行 hash 的开销会很大(时间复杂度 O ( N ) O(N) O(N)),如果是一个生命周期很短的字符串,则代价会很大
  2. 在实际实践中,大部分的字符串一般前面的字符就会不同,所以就算挨个比较也不会比较太多(如果计算 hashCode 则需要同时计算两个字符串,那么时间复杂度就会是 O ( M + N ) O(M+N) O(M+N)

出于对第一条的解读,在 HashMap 中做为 key 存在的字符串一般周期会存在的比较长所以计算 hashCode 是一个明智的选择

结合第一、二条来看,String#euqals 使用 hashCode 就显得不是很划算了

参考资料

  • 《Why does the equals method in String not use hash?》

彩蛋

在这里插入图片描述
把 chatGPT 都忽悠瘸了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/573760.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据安全复合治理框架和模型解读(0)

数据治理,数据安全治理行业在发展,在实践,所以很多东西是实践出来的,哪有什么神仙理论指导,即使有也是一家之说,但为了提高企业投产比,必要的认知是必须的,当前和未来更需要专业和创新。数据安全治理要充分考虑现实数据场景,强化业务安全与数据安全治理,统一来治理,…

学会了程序替换,我决定手写一个简易版shell玩一玩...

文章目录 &#x1f490;专栏导读&#x1f490;文章导读&#x1f427;程序进程替换&#x1f426;替换原理&#x1f426;替换函数&#x1f414;观察与结论&#x1f414;函数命名理解 &#x1f427;myshell编写&#x1f514;代码展示&#x1f514;效果展示 &#x1f427;myshell_p…

Vue电商项目--分页器制作

分页器静态组件 分页这个组件&#xff0c;不单单是一个页面用到了。多个页面同时用它,因此我们可以封装成一个全局组件 需要将这个分页结构拆分到components 通用的分页组件Pagination <template><div class"pagination"><button>1</butto…

【C语言】函数规则及入门知识

&#x1f6a9;纸上得来终觉浅&#xff0c; 绝知此事要躬行。 &#x1f31f;主页&#xff1a;June-Frost &#x1f680;专栏&#xff1a;C语言 ⚡注&#xff1a;此篇文章的 部分内容 将根据《高质量 C/C 编程指南》 —— 林锐 进行说明。该部分将用橙色表示。 &#x1f525;该篇…

新手建站:使用腾讯云轻量服务器宝塔面板搭建WP博客教程

腾讯云轻量应用服务器怎么搭建网站&#xff1f;太简单了&#xff0c;轻量服务器选择宝塔Linux镜像&#xff0c;然后在宝塔面板上添加站点&#xff0c;以WordPress建站为例&#xff0c;腾讯云服务器网来详细说下腾讯云轻量应用服务器搭建网站全流程&#xff0c;包括轻量服务器配…

html5视频播放器代码实例(含倍速、清晰度切换、续播)

本文将对视频播放相关的功能进行说明&#xff08;基于云平台&#xff09;&#xff0c;包括初始化播放器、播放器尺寸设置、视频切换、倍速切换、视频预览、自定义视频播放的开始/结束时间、禁止拖拽进度、播放器皮肤、控件按钮以及播放控制等。 图 / html5视频播放器调用效果&a…

java web 基础springboot

1.SprintBootj集成mybaits 连接数据库 pom.xml文件添加依赖 <!-- mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><!-- …

学习HCIP的day.09

目录 一、BGP&#xff1a;边界网关路由协议 二、BGP特点&#xff1a; 三、BGP数据包 四、BGP的工作过程 五、名词注解 六、BGP的路由黑洞 七、BGP的防环机制—水平分割 八、BGP的基本配置 一、BGP&#xff1a;边界网关路由协议 是一种动态路由协议&#xff0c;且是…

花果山博客

1&#xff1a;前言 2&#xff1a;项目介绍 3&#xff1a;统一返回结果 4&#xff1a;登录功能实现 前言 简单介绍一个写这个博客的目的。 因为之前学开发都是学完所需的知识点再去做项目&#xff0c;但是这时候在做项目的过程中发现以前学过的全忘了&#xff0c;所以为了减少这…

Vue3导入Element-plus方法

先引入依赖 npm install element-plus --savemain.js中要引入两个依赖 import ElementPlus from element-plus; import "element-plus/dist/index.css";然后 这个东西 我们最好还是挂载vue上 所以 还是 createApp(App).use(ElementPlus)然后 我们可以在组件上试一…

腾讯云轻量服务器镜像安装宝塔Linux面板怎么使用?

腾讯云轻量应用服务器宝塔面板怎么用&#xff1f;轻量应用服务器如何安装宝塔面板&#xff1f;在镜像中选择宝塔Linux面板腾讯云专享版&#xff0c;在轻量服务器防火墙中开启8888端口号&#xff0c;然后远程连接到轻量服务器执行宝塔面板账号密码查询命令&#xff0c;最后登录和…

从零搭建微服务-认证中心(二)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff1a;https://gitee.com/csps/mingyue 文档地址&#xff1a;https://gitee.com/csps/mingyue/wikis 创建新项目 MingYue Idea 创建 maven 项目这…

操作系统第五章——输入输出管理(下)

提示&#xff1a;枕上诗书闲处好&#xff0c;门前风景雨来佳。 文章目录 5.3.1 磁盘的结构知识总览磁盘 磁道 扇区如何从磁盘中读/写数据盘面 柱面磁盘的物理地址磁盘的分类知识回顾 磁盘调度算法知识总览磁盘的读写操作需要的时间先来先服务算法FCFS最短寻找时间优先SSTF扫描算…

SVG图形滤镜

SVG有提供Filter(滤镜)这个东西&#xff0c;可以用来在SVG图形上加入特殊的效果&#xff0c;像是图形模糊化、产生图形阴影、将杂讯加入图形等。以下介绍的是图形模糊化、产生图形阴影这2个滤镜效果。 浏览器对于SVG Filter的支援 SVG : 滤镜 (仅列出部分有使用到的属性) <…

【数据结构】超详细之实现栈

栈的实现步骤 栈的介绍栈的初始化栈的插入(入栈)栈的出栈获取栈顶元素获取栈中有效元素个数检测栈是否为空销毁栈栈元素打印 栈的介绍 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xf…

快捷转换/互转 Markdown 文档和 TypeScript/TypeDoc 注释

背景 作为文档工具人&#xff0c;经常需要把代码里面的注释转换成语义化的 Markdown 文档&#xff0c;有时也需要进行反向操作。以前是写正则表达式全局匹配&#xff0c;时间长了这种方式也变得繁琐乏味。所以写了脚本来互转&#xff0c;增加一些便捷性。 解决方案 注释转 M…

【C++】初遇C++

认识C C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。对于复杂的问题&#xff0c;规模较大的程序&#xff0c;需要高度的抽象和建模时&#xff0c;C语言则不合适。为了解决软件危机&#xff0c; 20世纪80年代&#xff0c; 计算机界提出了OOP(object orient…

学好网络安全,每年究竟能挣多少钱呢?

薪资的高低&#xff0c;应该是想要转行网络安全的同学最关心的话题了。毕竟薪资是个人水平和自我价值的体现嘛。&#xff08;文末资料&#xff09; 今天就展开谈谈网络安全行业的薪资吧。 先来看张图&#xff0c; 大家在求职时都有一个期望薪资&#xff0c;企业会有一个实际薪…

5月的面试难度有点大....

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

R语言实践——使用rWCVP映射多样性

使用rWCVP映射多样性 加载库工作流1. 物种丰富度2. 特有物种丰富度3. 特定区域的物种热力图 加载库 library(rWCVP) library(tidyverse) library(sf) library(gt)工作流 1. 物种丰富度 我们可以使用 wcvp_summary 将所有物种的全球出现数据压缩为每个 WGSRPD 3 级区域的原始…