唯一的hashCodes不足以避免冲突

有一个常见的误解,即如果您具有唯一的hashCode(),则不会发生冲突。 虽然唯一或几乎唯一的hashCodes很好,但这还不是故事的结局。

问题在于HashMap的大小不是无限的(或大小至少为2 ^ 32),这意味着hashCode()的数量必须减少为较小的位数。

HashMap以及HashSet和LinkedHashMap的工作方式是按以下方式对位进行突变:

h ^= (h >>> 20) ^ (h >>> 12);
return h ^ (h >>> 7) ^ (h >>> 4);

然后为最低位应用掩码以选择存储区。 问题在于,即使像Integer一样使用唯一的hashCode(),也会有具有不同哈希码的值映射到同一存储桶。 您可以研究Integer.hashCode()的工作方式:

public static void main(String[] args) {Set integers = new HashSet<>();for (int i = 0; i <= 400; i++)if ((hash(i) & 0x1f) == 0)integers.add(i);Set integers2 = new HashSet<>();for (int i = 400; i >= 0; i--)if ((hash(i) & 0x1f) == 0)integers2.add(i);System.out.println(integers);System.out.println(integers2);}static int hash(int h) {// This function ensures that hashCodes that differ only by// constant multiples at each bit position have a bounded// number of collisions (approximately 8 at default load factor).h ^= (h >>> 20) ^ (h >>> 12);return h ^ (h >>> 7) ^ (h >>> 4);
}

打印:

[373, 343, 305, 275, 239, 205, 171, 137, 102, 68, 34, 0]
[0, 34, 68, 102, 137, 171, 205, 239, 275, 305, 343, 373]

条目的顺序与之相反,因为它们是作为HashMap的链接列表而添加的,将所有条目置于同一存储桶中。

解决方案?

一个简单的解决方案是让一个存储桶变成一棵树,而不是一个链表。 在Java 8中,它将对字符串键执行此操作,但是可以对所有可比较类型AFAIK执行此操作。

另一种方法是允许使用自定义哈希策略,以使开发人员避免此类问题,或者在每个集合的基础上随机化突变,从而将应用程序的成本摊销到应用程序中。

其他注意事项

我倾向于支持64位哈希码,尤其是支持复杂对象的哈希码。 哈希码本身发生冲突的可能性很小,并且很好地支持非常大的数据结构。 例如数十亿。

参考: 唯一的hashCodes不足以避免我们的JCG合作伙伴 Peter Lawrey在Vanilla Java博客上发生冲突 。

翻译自: https://www.javacodegeeks.com/2013/10/unique-hashcodes-is-not-enough-to-avoid-collisions.html

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

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

相关文章

Spring Boot使用AOP实现拦截某个方法

1、引入.jarl文件依赖 <!-- Spring Boot Web 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 从依赖信息里移除 Tomcat配置 --><exclusions><exc…

DB 数据同步到数据仓库的架构与实践

背景 在数据仓库建模中&#xff0c;未经任何加工处理的原始业务层数据&#xff0c;我们称之为ODS&#xff08;Operational Data Store&#xff09;数据。在互联网企业中&#xff0c;常见的ODS数据有业务日志数据&#xff08;Log&#xff09;和业务DB数据&#xff08;DB&#xf…

起名与选择器~(总结类、持续更新系列)

废话没有&#xff0c;直接干活 一、起名方式&#xff1a;1.元素自身的标签名&#xff1b; 2.利用 class 属性自定义名称&#xff1b; 3.利用 id 属性自定义名称。共三种&#xff0c;其中class使用居多。 起名规范:不能用汉字起 第一个字母不能是特殊符号 第一个字母必须是英文字…

java log.error_Logger.error打印错误异常的详细堆栈信息

一、问题场景使用Logger.error方法时只能打印出异常类型&#xff0c;无法打印出详细的堆栈信息&#xff0c;使得定位问题变得困难和不方便。二、先放出结论Logger类下有多个不同的error方法&#xff0c;根据传入参数的个数及类型的不同&#xff0c;自动选择不同的重载方法。当e…

笔记本电脑怎么清理灰尘_手机声音越用越小怎么办?一段黑科技音波就能清理扬声器灰尘...

大家好&#xff0c;欢迎收看科技狐&#xff0c;我是小狐。我们都知道&#xff0c;随着手机的使用时间越来越长&#xff0c;手机扬声器里面会积赞一些灰尘。因此手机的声音就会变得越来越小。有时候连电话铃声都听不清楚&#xff0c;说实话我就是这个样子&#xff0c;为此我困扰…

Java方法中的参数太多,第8部分:工具

在我的系列文章的前七篇文章中&#xff0c;有关处理Java方法中期望的参数过多的内容集中在减少方法或构造函数期望的参数数量的替代方法上。 在本系列的第八篇文章中&#xff0c;我将介绍一些工具&#xff0c;这些工具可帮助您确定可能存在过多参数的情况&#xff0c;并在出现这…

Java _类 相关知识

成员变量java对象的属性就是成员变量,其实成员变量就是指普通的变量,可以设置初始值,也可以不设置.当不设置时,会被设置为默认值.(当成员变量前面有private关键词时,说明定义了一个私有成员) java中使用class关键词定义一个类, 成员方法java语言中使用成员方法来对应于类对象的…

linux操作系统好吗_国内可以通过安卓+termux打造出适用手机平板和电脑全平台最好的操作系统...

我觉得国内可以基于安卓上的termux要搞一个termux软件商店&#xff0c;用户可以从termux软件商店里安装c,c,java,python,vim,jupyter notebook,php&#xff0c;R等软件&#xff0c;并在安卓手机和安卓平板桌面上生成这些软件的图标&#xff0c;用户可以直接点击这些python,vim,…

java it_关于 Java Iterator(迭代器)学习笔记

相信 “迭代” 对于Java程序员来说并不陌生(当然&#xff0c;其他语言的程序员也是如此)&#xff0c;在处理数据时&#xff0c;不可避免地会存在对数据的大量遍历操作。对于我自己而言&#xff0c;学习使用Java语言两年时间&#xff0c;对于“迭代”的概念还停留在 for:each,fo…

scss-!optional

optional翻译成汉语具有"可选的"的意思。顾名思义&#xff0c;!optional标记前面的扩展不必须生成一个新的选择器。看一段SCSS代码片段&#xff1a; p{color:red;extend .notice } 由于并不存在一个名为notice的样式类&#xff0c;所以上述代码会报错。代码修改如下&…

Http(s)与后台交互方式

前言 Http(s)是前后端交互的主要方式之一&#xff0c;交互技术主要有:Ajax(XMLHttpRequest)、Fetch、地址跳转(window.open、location.href)。Http(s)与后台交互传递数据的部分有:请求网址、请求头、请求主体、响应头、响应主体 请求网址 请求网址是通过pathname或search进行传…

Python的字符串格式化

Python的字符串格式化有两种方式: 百分号方式、format方式 百分号的方式相对来说比较老&#xff0c;而format方式则是比较先进的方式&#xff0c;企图替换古老的方式&#xff0c;目前两者并存。 This PEP proposes a new system for built-in string formatting operations, in…

使用Spring Form标签探索Spring Controller

在上一篇文章中 &#xff0c;我向您展示了如何使用Spring控制器处理纯HTML表单。 但是处理表单的更强大的方法是使用Spring的ModelAttribute及其spring:form标签。 我将向您展示如何通过修改上一篇文章的项目设置从这里开始。 我们将简单地修改Comment表单和控制器以使用此功能…

predict函数 R_学习|R语言做机器学习的常用函数总结

预测函数&#xff1a;predict() type"prob"判别该量度的昆虫归类为A、B和C的概率&#xff1b;type"response"&#xff1a;判别该量度的昆虫的类别&#xff1b;预测分类的概率的函数predict(…, type)参数type&#xff1a;R语音里面不同模型&#xff0c;参数…

微信小程序:动画(Animation)

简单总结一下微信动画的实现及执行步骤。 一、实现方式 官方文档是这样说的&#xff1a;①创建一个动画实例 animation。②调用实例的方法来描述动画。③最后通过动画实例的 export 方法导出动画数据传递给组件的 animation 属性。 因为小程序是数据驱动的&#xff0c;给这句话…

java map clone_Java中HashMap的clone()方法: java.util.HashMap.clone() - Break易站

Java中的HashMapjava.util.HashMap.clone()方法用于返回所提到的哈希映射HashMap的浅表副本。它只是创建了map的副本。HashMap.clone句法&#xff1a;Hash_Map.clone()参数&#xff1a;该方法不接受任何参数。返回值&#xff1a;该方法只返回HashMap的副本。下面的程序用于说明…

计算模块分析

模块需要实现的功能&#xff1a;1、实现原始深度计算&#xff1a;五个输入、一个输出值和一个输出使能信号&#xff1b; 2、计算幅度值&#xff08;这个功能是一个使能控制的&#xff09;这个的话就是一个行结束信号和一个行输出使能信号&#xff1b; 3、需要告诉相连的模块什么…

为什么我们不应该使用过多的线程

总览 有一个普遍的论点&#xff0c;因为我们有很多核心&#xff0c;并且将来还会有更多核心&#xff0c;所以我们必须使用它们。 我们只是需要找到使用它们的最佳方法&#xff0c;而仅仅是因为我们不能意味着我们应该这样做。 我们的目标是什么&#xff1f; 使用多个线程的充分…

SSM+solr 通过商品搜索学习solr的简单使用

学习了一下https://github.com/TyCoding/ssm-redis-solr这个github上的solr搜索功能&#xff0c;现在来记录一下。 我的理解就是solr有点类似于数据库&#xff0c;但它是有索引的数据库&#xff0c;按很多字段建立索引&#xff0c;可能是b树或者散列索引&#xff0c;然后就能够…

可以使用中文作为变量名_次氯酸可以作为伤口消毒使用吗?

次氯酸可以作为伤口消毒使用吗&#xff1f;次氯酸在经过2020年的洗礼&#xff0c;已然成为常态化&#xff0c;它对于人体是否有害&#xff0c;也是人们关注的焦点。对于那些还不太了解次氯酸的群体做一下简短科普。什么是次氯酸&#xff1f;次氯酸&#xff08;HCIO&#xff09;…