HashMap是JDK提供的经典容器之一,最近刚好时间充裕,于是自己看了一遍hashMap的源码实现,不同版本的JDK,HashMap的实现方式有所不同,本文主要针对JDK1.8的源码进行分析,至于各版本实现方式的不同,本文不做讨论,下面直接开始。
一、hash函数分析
map的put方法,首先调用的就是hash函数,返回key的hash值,其函数方法如下:
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); }
函数结构比较简单,但是我相信很多人看到这里是懵的,不知道函数这样处理的目的是什么,下面写了一个小demo来帮助大家理解这个函数。
执行结果如下:
上面的结果只是为了验证我的推导过程的正确性,用Integer.toBinaryString()这个函数可以得到一个10进制数的二进制有效位,因为位运算都是基于二进制的,所以说明中我进行了补全,其实一句话说明就是,这个hash函数获取的就是key的hashCode的值的二进制数及其自身无符号右移16位之后的值的异或运算后的结果,至于为什么要这么做,主要是为了将这个二进制数(32位)的低16位和高16位打乱,使其散列尽可能均匀。
备注:右移16位,相当于将32位的二进制数的高16位移动到低16位,高16位用0补齐,可以根据我给的例子观察出来。
二、HashMap的put()方法源码注释分析
上面的分析过程中,有两处用到了resize函数,一是table未初始化的时候,一是新增元素后,如果元素总数size大于threshold的时,下面详细分析下这个函数。
三、HashMap扩容函数resize()方法源码注释分析
三、HashMap的get()方法源码注释分析
以上就是HashMap几个重要函数的源码分析,当然还有比较棘手的红黑树的处理,下次再专门写一篇文章说明。
原文地址:https://www.cnblogs.com/green-technology/p/hash_map.html