JDK1.8 HashMap初步分析

1、JDK1.8对HashMap和ConcurrentHashMap做了很大的修改,我们今天只对其JDK1.8的HashMap做初步的剖析

HashMap 主要的数据结构为数组+链表+红黑树

2、通过对源码进行分析,有几个重要的参数

默认的初始化数组大小为16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; 
最大的数组容量
static final int MAXIMUM_CAPACITY = 1 << 30;
装载因子,当hashmap的size达到数据容量*DEFAULT_LOAD_FACTOR时候,会进行扩容,每次扩容都扩一倍
static final float DEFAULT_LOAD_FACTOR = 0.75f;
为了解决hash冲突问题,hash值相同采用链表的形式,但是在1.8中,当链表长度超过8,会采用红黑树的数据结构,查找复杂度从n降为logn
static final int TREEIFY_THRESHOLD = 8;
在删除或者扩容的时候,当数组某个index下的红黑树节点size下降到6以下,红黑树转换为链表
static final int UNTREEIFY_THRESHOLD = 6;
当数组的容量小于64时,当数据index下超过8个节点,不采用红黑树,而是扩容数组,当超过64,size没有达到数组容量的0.75时,一个index下超过8个才使用红黑树
static final int MIN_TREEIFY_CAPACITY = 64;

对源码做一些说明
key值的hash计算
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}

根据key值的hashcode,与自身hash无状态右移16位做一个异或操作

static final int tableSizeFor(int cap) {
    int n = cap - 1;
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

初始化的容量大小,hash希望大小都是2的幂次方,取大于等于初始化大小的最小2的幂次方,目的是为了hash映射的时候

(n - 1) & hash相当于hash对n取模,尽可能把hash映射到不同的数组index下,如果不是2的幂次方,有些槽位可能永远不会映射到。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值