HashMap重点源码剖析

Posted xtz2018

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap重点源码剖析相关的知识,希望对你有一定的参考价值。

HashMap源码阅读:

1,概述

2,HashMap核心成员变量

3,HashMap构造函数

4,HashMap核心方法

1,概述

搞java的人,都应该知道hashMap的底层数据结构是一个数组+链表(+红黑树)。

大体思路:首先是基于key做hash操作,然后与数组长度取模,定位到某个数组位置。如果冲突了(可能是hash冲突,或者是hash值与长度取模之后),就会在该数组位置再挂一个链表。jdk1.8以后当链表长度达到8之后,就转化为红黑树(因为链表的时间复杂度是N,红黑树是log N),提升了性能。

以上是大概思路,其实jdk源码是优化的,比如hash算法,取模操作这些都是位运算来替代的,等到后面看源码的时候再来好好撸撸。

2,HashMap核心成员变量

先看看HashMap的核心成员,先了解下这些,后面源码部分都会看到。

#默认主的数据结构数组的初始化大小:16
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4
#数组的最大大小
static final int MAXIMUM_CAPACITY = 1 << 30;
#负载因子
static final float DEFAULT_LOAD_FACTOR = 0.75f;
#将链表转化为红黑树的临界值
static final int TREEIFY_THRESHOLD = 8;
#将红黑树转化为链表的临界值
static final int UNTREEIFY_THRESHOLD = 6;
#转变成树的数组的最小长度,小于该值则不会进行树化
static final int MIN_TREEIFY_CAPACITY = 64;
#主的数据结构数组
transient Node<K,V>[] table;
#map的键值对的集合
transient Set<Map.Entry<K,V>> entrySet; 
#map中键值对的数量
transient int size;
#用于统计map修改次数的计数器,用于fail-fast抛出ConcurrentModificationException
transient int modCount;
#数组长度大于该值,则数组会进行扩容
int threshold;
#负载因子
final float loadFactor;  

 3,HashMap构造函数

hashMap构造函数有4种:

技术图片

3.1 无参构造函数

    public HashMap() 
#初始化只是设置了默认的负载因子为0.75
this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted

3.2 传初始化容量构造函数

    public HashMap(int initialCapacity) 
#推荐使用这种(因为数组扩容,数据再重新分配是比较消耗性能的。)
this(initialCapacity, DEFAULT_LOAD_FACTOR);

3.3 传初始化容量和负载因子

    public HashMap(int initialCapacity, float loadFactor) 
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);
        this.loadFactor = loadFactor;
#tableSizeFor()方法用于将传入的初始化容量转化为大于等于2的N次方的最接近初始化容量的数。比如传入7,threshold=8。threshold前面说过,这个数其实是当数组达到该长度,就会进行扩容
this.threshold = tableSizeFor(initialCapacity);

 

                                                                                                

以上是关于HashMap重点源码剖析的主要内容,如果未能解决你的问题,请参考以下文章

Java HashSet和HashMap源码剖析

转:Java集合源码剖析HashMap源码剖析

JDK 源码剖析 —— HashMap

HashMap就是这么简单源码剖析

HashMap源码剖析

python部分重点底层源码剖析