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重点源码剖析的主要内容,如果未能解决你的问题,请参考以下文章