深圳幻海软件技术有限公司 欢迎您!

HashMap的数据结构

2023-06-25

1,HashMap集合简介HashMap基于哈希表的Map接口实现,是以key-value存储形式存在,即主要用来存放键值对。HashMap的实现不是同步的,这意味着它不是线程安全的。它的key、value都可以为null。此外,HashMap中的映射不是有序的。JDK1.8之前的HashMap由数

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索引的值。计算索引的方法如下:

  1. /**
  2. * 根据key求index的过程
  3. * 1,先用key求出hash值
  4. */
  5. static final int hash(Object key) {
  6. int h;
  7. return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
  8. }


//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=数组容量×加载因子。

KV键值对数量

int size
文章知识点与官方知识档案匹配,可进一步学习相关知识
算法技能树首页概览48400 人正在系统学习中