hashMap 源码解读理解实现原理和hash冲突

hashMap 怎么说呢。 我的理解是 外表是一个set 数组,无序不重复 。 每个set元素是一个bean ,存着一对key value

 

看看代码吧

package test;import java.util.HashMap;
import java.util.Map.Entry;public class HashMaptest {public static void main(String[] args) {HashMap<String, String> map = new HashMap<String, String>();String aa = "张三";String bb = "李四";map.put(aa, "22");map.put(bb, "34234");map.put("张三", "223");System.out.println(aa.hashCode());System.out.println(bb.hashCode());for (Entry<String, String> entry : map.entrySet()) {System.out.println(entry.getKey());// System.out.println(entry.getValue());
        }}}

打印的结果是:

774889
842061
李四
张三

可以看到, 虽然张三是先插进去的, 但是确在后面打印出来,说明这个数组不是有序的, 不是list;

虽然aa  的 hashcode=774889 大于bb 的, 肯定不是根据大小插入的,应该是把 得到的hashcode 取余 , 例如  6%7 = 6 , 9%(7+1)=1 ,6>1  ,所以9 在前面,这里为什么是  第一个除以7 ,第二个进来确实% 8呢;

因为hash算法是 这样的:

int hash = key.hashCode(); // 这个hashCode方法这里不详述,只要理解每个key的hash是一个固定的int值
int index = hash % Entry[].length;
Entry[index] = value;

这里看到  Entry[].length 一直在增加的;

 

所以就会遇到hash冲突, 总有碰到取余后一样的;

好了,举个例子:

比如 key="张三", hashcode=666 ,entry的size是 100   666%100=66  ;存在  66 位置上。  这个时候 key="李四" 要插入了, hashcode =6666 entry的size是 6600  6666%6600=66 , 这样 66 位置就hash冲突了;

这里和我代码写的覆盖不是一回事 。 代码的 key  相同,这里在特别说明下:可能有人说, 两个张三的hashcode 一样, 不同时候插入,entry 的 size不是不一样吗, 那就不会覆盖了? 这么想是错误的, 其实 map 插入的时候是先比较equals  的, 发现,咦 ,相同, 直接覆盖原值

:附上 hashMap的Put 方法源码:

 

   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;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}

 

 

 

可能比较难懂, 主要在这句:

    if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }

已存在的key ,之而立是直接覆盖的。

 

转载于:https://www.cnblogs.com/zgghb/p/6385774.html

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

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

相关文章

浙江大学linux网络通信,浙江大学钟财军副教授——“Wireless Powered Communication Networks”...

2016年5月17日&#xff0c;浙江大学钟财军副教授应徐正元教授邀请在中科大西区科技实验楼东楼十层1011会议室做了一场题为“Wireless Powered Communication Networks”的学术报告。报告会由龚晨教授主持&#xff0c;共50余名师生参加。此次报告会得到了“中科院无线光电通信重…

自定义Spring Data JPA存储库

Spring Data是一个非常方便的库。 但是&#xff0c;由于该项目是一个相当新的项目&#xff0c;因此功能不佳。 默认情况下&#xff0c;Spring Data JPA将基于SimpleJpaRepository提供DAO的实现。 在最近的项目中&#xff0c;我开发了一个定制的存储库基类&#xff0c;以便可以在…

[基础]PeopleSoft中的作业和调度作业集合定义

PeopleSoft进程调度器可以使一个或多个进程作为一个组。这个组在PeopleSoft中被称为作业(Job)。 PeopleSoft进程被定义为单个任务&#xff0c;程序或例程&#xff0c;例如cobol程序或AE程序或客户端运行的SQR。 作业由一个或多个相同或不同类型的进程组成&#xff0c;他们作为一…

体验 WebFont,网页上的艺术字

在最新项目中&#xff0c;由于要频繁使用艺术字&#xff0c;而用户设备没有此字体&#xff0c;因此以往的经验都是使用图片...所以在同事的瞩目期许之下&#xff0c;我开始实验研究这个问题的解决方案1. 直接使用字体文件font-face {font-family: xxxx;src: url(../img/汉仪秀英…

linux文件分别打包命令,Linux文件打包命令

15.1 gzipgzip(1)是GNU的压缩程序。它只对单个文件进行压缩。基本用法如下&#xff1a;$ gzip filename程序执行以后&#xff0c;文件名会变成filename.gz&#xff0c;而且一般情况下大小会比原文件要小。注意&#xff0c;程序并不新建一个新的文件filename.gz,而是将filename变…

Play 2.0框架和XA交易

XA事务非常有用&#xff0c;而且开箱即用&#xff0c;今天的Play 2.0不支持它们。 在这里&#xff0c;我展示了如何添加该支持&#xff1a; 首先&#xff0c;介绍一些XA有用的示例&#xff1a; –如果您使用来自两个不同persistence.xml的实体&#xff0c;则JPA使用两个物理连…

java代码注释规范

java代码注释规范 一、规范存在的意义 应用编码规范对于软件本身和软件开发人员而言尤为重要&#xff0c;有以下几个原因&#xff1a;1、好的编码规范可以尽可能的减少一个软件的维护成本 , 并且几乎没有任何一个软件&#xff0c;在其整个生命周期中&#xff0c;均由最初的开…

win10 hyper-v 虚拟机ping不通宿主机问题

在Windows10 Hyper-V 中安装 Linux (Centos6.9)虚拟机无法 ping 通宿主机 这种情况下关闭 Windows 防火墙就能ping通了&#xff0c;当然关闭防火墙不安全。所以需要 做以下步骤: 控制面板-》系统和安全-》Windows防火墙-》高级设置-》入站规则 启用下图被红框选中的两个选…

linux方法参数,Linux的sysctl 命令 参数

Linux内核通过/proc虚拟文件系统向用户导出内核信息&#xff0c;用户也可以通过/proc文件系统或通过sysctl命令动态配置内核。比如&#xff0c;如果我们想启动NAT&#xff0c;除了加载模块、配置防火墙外&#xff0c;还需要启动内核转发功能。我们有三种方法&#xff1a;1. 直接…

Java枚举:您拥有优雅,优雅和力量,这就是我所爱!

当Java 8即将面世时&#xff0c;您确定您对Java 5中引入的枚举很了解吗&#xff1f; Java枚举仍然被低估了&#xff0c;很可惜&#xff0c;因为它们比您想象的要有用&#xff0c;它们不仅仅用于通常的枚举常量&#xff01; Java枚举是多态的 Java枚举是可以包含行为甚至数据的…

C#删除和清空文件夹的程序

/// <summary>/// 清空指定的文件夹&#xff0c;但不删除文件夹/// </summary>/// <param name"dir"></param>private void DeleteFolder(string dir){foreach (string d in Directory.GetFileSystemEntries(dir)){if (File.Exists(d)){try{…

2)网页请求顺序

&#xff08;1&#xff09;分析浏览器访问一个网页的完整流程逻辑过程&#xff1a;http&#xff1a;//www.abc.com/def/ 转载于:https://www.cnblogs.com/xiaoyoucai/p/7306246.html

JavaOne 2012:非阻塞数据结构如何工作?

当我查看今天的日程安排时&#xff0c;我感到有些惊讶&#xff0c;并指出我目前计划今天参加的所有会议都在希尔顿举行。 当我意识到JavaOne演示文稿中大约有一半是在希尔顿酒店中并且似乎按路线大致定位时&#xff0c;这变得有些不足为奇了。 Tobias Lindaaker &#xff08; 新…

c语言箭头指针的作用,C语言中,结构体成员变量的点和箭头

C语言中&#xff0c;调用成员变量用点还是用箭头&#xff0c;取决于当前的ID是指针还是结构体本身。如&#xff1a;typedef struct {float height;float weight;} Person;int main(int argc, char *argv[]) {Person jiushen;Person *lengleng (Person *)malloc(sizeof(Person)…

JavaOne 2012:调查JVM水晶球

我回到了希尔顿的A / B广场参加星期一的第四届会议&#xff0c;但首先去了希尔顿的顶层收拾午餐。 我每年都在JavaOne的第一天被提醒&#xff0c;涉及到每个人的第一天的午餐获取过程令人惊讶地令人沮丧。 我知道我在JavaOne的第一年的经历使我有些困惑&#xff0c;因为我不确定…

测试遇到的问题

多人合作测试 多人员合作测试&#xff0c;应尽量保证测试平台统一&#xff0c;处理流程统一&#xff0c;相互之间保持实时沟通。问题的处理进度应保证所负责的所有测试人员第一时间实时更新。 多人测试应做到2人或以上进行交叉测试。 转载于:https://www.cnblogs.com/liuliu-wo…

Jquery Memo

jQuery选择器 $( "#id" ) $( ".class" )$( "element" )全选择器&#xff08;*选择器&#xff09; * {padding: 0; margin: 0;}//子选择器 //$(div > p) 选择所有div元素里面的子元素P//后代选择器 //$(div p) 选择所有div元素…

c#语言输出字符串长度,C#统计字符长度(汉字占2个字符)

在C#编程过程中&#xff0c;通过String类的Length属性可以获取对应字符串的长度&#xff0c;但是细心的读者可能注意到了&#xff0c;String类的Length属性返回的是字符串中Char对象的个数&#xff0c;也就是说&#xff0c;一个汉字的长度为1&#xff0c;对此&#xff0c;MSDN的…

使用JMSTester对JMS层进行基准测试

对于我去过的大多数客户端&#xff0c;使用ActiveMQ扩展JMS消息传递层是一个优先事项。 有多种方法可以实现这一目标&#xff0c;但毫无疑问&#xff0c;创建基准测试并在实际硬件上分析架构&#xff08;或者正如我的同事Gary Tully所说的“询问机器”&#xff09;是第一步。 但…

Js引擎解析执行 阅读笔记

Js引擎解析执行 阅读笔记 一篇阅读笔记http://km.oa.com/group/2178/articles/show/145691?kmrefsearch&from_page1&no1 早期:遍历语法树 Js引擎最早使用的是遍历语法树方式 &#xff08;syntax tree walker&#xff09; 分为两步 词法分析语法分析词法分析 i a b *…