1,HashMap集合简介
HashMap基于哈希表的Map接口实现,是以key-value存储形式存在,即主要用来存放键值对。HashMap的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。
JDK1.8之前的HashMap由数组+链表组成的,数组是HashMap的主体,链表则是主要为了节解决哈希碰撞(两个对象调用的hashCode方法计算的哈希码值一致导致计算的数组索引值相同)而存在的(“拉链法”解决冲突)。
JDK1.8之后在解决哈希冲突时有了较大的变化,当链表长度大于阈值(或者红黑树的边界值,默认为8)并且当前数组的长度大于64时,此时此索引位置上的所有数据改为使用红黑树存储。
key-value实例
由于它的key、value都为null,所以在插入的时候会根据key的hash去计算一个index索引的值。计算索引的方法如下:
/**
* 根据key求index的过程
* 1,先用key求出hash值
*/
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
//2,再用公式index = (n - 1) & hash(n是数组长度)
这里的Hash算法本质上就是三步:取key的hashCode值、高位运算、取模运算。
这样的话比如说put("A",王炸),插入了key为"A"的元素,这时候通过上述公式计算出插入的位置index,若index为3则结果如下(即hash("A")=3):
2.影响HashMap性能的两个重要参数以及HashMap的几个重要成员变量
1.初始容量
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
初始容量用来规定哈希表数组的长度,默认值为16,因为16是2的整数次幂的原因,再小数据量下的情况下,能减少哈希冲突,提高性能。在大存储容量数据的时候,也尽量将数组长度定义为2的幂次方,这样能更好的与索引计算公式i=(n-1)&hash配合使用,从而提升性能。
2.加载因子
final float loadFactor;、
用来表示HashMap集合中元素的填满程度,默认为0.75f。越大则表示允许填满的元素就多,集合的空间利用率就越高,但是冲突的机会增加。反之,越小则冲突的机会就会越少,但是空间很多就浪费。
所以在设置初始容量时,应优先考虑到初始容量及其他加载因子,预估设置初始容量,最大程度的减少rehash重建内部数据结构的次数,极大的减少了扩容操作。
底层数组
transient Node<K,V>[] table;
保存KV键值对的数组,每个KV键值对都被封装成一个Node对象。
最大容量
static final int MAXIMUM_CAPACITY = 1 << 30;
HashMap的最大容量值,扩容时如果超出,则不扩容。
扩容阈值
int threshold
用于判断数组是否需要扩,扩容阈值threshold=数组容量×加载因子。文章来源:https://www.toymoban.com/news/detail-465340.html
KV键值对数量文章来源地址https://www.toymoban.com/news/detail-465340.html
int size
到了这里,关于HashMap的数据结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!