HashMap与ConcurrentHashMap 的数据结构

HashMap:
数组与链表,每个数据对应一个链表
插入时进行与运算
http://blog.csdn.net/tingting256/article/details/52475422
数组默认长度16,当超过16*0.75=12时,组数长度变为16*2->叫resize,毁
HashMap的基础构造器HashMap(int initialCapacity, float loadFactor)带有两个参数,它们是初始容量initialCapacity和加载因子loadFactor。
https://www.cnblogs.com/ITtangtang/p/3948406.html
相同含义的两个对象,插入同一个key:
http://blog.csdn.net/zbuger/article/details/51029898

为什么是数组长度是16
计算卡槽点时,具体落到哪个数组时,做与运算时
hash(hashCode(key)) & (length-1) -> 会落到位置范围内
二进制:Interger.toBinaryString(15);
是容量到了12会扩容,在扩容的时候更多的节点不需要重新计算到新槽点, hash之后的桶的角标是不变的。

为什么0.75
过低,小一点:扩容频繁。
过高,大一点:扩容不容易发生,数组重复概率增加,导致get和put时间增多,冲突需要遍历大量链表空间。

final int hash(Object key)里有>>>,>>>
降低重复冲突概率

深入理解: https://www.zhihu.com/question/20733617
“扰动函数”混合原始哈希码的高位和低位,加大低位随机性,为了减少数组碰撞概率,减少10%。
Java 8觉得扰动做一次就够了,做4次的话,多了可能边际效用也不大,所谓为了效率考虑就改成一次了。
当获取对象时get,hash找到数组槽位,循环链表,通过键对象的equals()方法找到正确的键值对,然后返回值对象。

HashTable:
数组默认长度11
http://blog.csdn.net/xuefeng0707/article/details/40834595
继承的父类不同
线程安全性不同
key和value是否允许null值
hash值不同,插入算法也不同,hashtable取取模运算,hashmap与运算。
是否提供contains方法
http://blog.csdn.net/fujiakai/article/details/51585767

ConcurrentHashMap:
http://blog.csdn.net/yan_wenliang/article/details/51029372

segment数组,每个数组是一个hashtable,里面有分段锁
多线程put时,当同一数组存储时线程加锁,不同数组时,没有锁,效率的提升。

猜你喜欢

转载自572327713.iteye.com/blog/2405603