小白初识HashMap
HashMap
HashMap简介
HashMap是Map接口的一个实现类,是一个集合类。常用的Map实现类除了HashMap还有LinkedHashMap、TreeMap、HashTable(目前属于遗留类,被ConcurrentHashMap替代);
相比于HashMap,LinkedHashMap及TreeMap保证了插入顺序在这里不多做研究。而HashTable
保证了线程安全。但由于效率没有ConcurrentHashMap高而被取代。
HashMap的数据结构
在1.8之前HashMap的底层数据结构是数组加链表,1.8之后变为了数组加链表加红黑树。
为什么 HashMap1.8之后加入了红黑树
因为HashMap键值对的储存位置是根据key的hashCode进行高位运算及取模运算(总之就是一系列
特别牛逼的算法)而得到存储目标数组的下标。当哈希碰撞评率较高时,会造成该下标处的链表过长。
导致每次查询时都要遍历整个链表,查询效率太低。此时的时间复杂度为O(n)。
而引入了红黑树之后,当链表长度大于8时,此Node就会转化为TreeNode。也就是转化为红黑树结构。
此时时间复杂度就会降低至O(logn),大大增加了查询效率。
什么是哈希碰撞
简单来说当两个不同的key经过哈希运算得出的储存位置一样时,此时就称为发生了哈希碰撞。
1.8后HashMap的put过程
判断数组是否为null或者数组长度是否为0,若为0则进行扩容。不为0则判断当前数组下有没有数据,没有则直接插入。若有数据则对比是否和首条数据的key相同若相同则覆盖。若不同则判断当前node是否为TreeNode若是,则直接插入或覆盖。若不是则判断链表长度是否大于8,若大于则转为TreeNode,若不大于则插入或覆盖。最后会判断当前数组长度是否大于等于设定的阈值,若条件满足则进行扩容。
HashMap的几个核心参数
length; // 数组长度
threshold; // 所能容纳的key-value对极限
loadFactor; // 负载因子
modCount; //内部结构发生变化的次数(这里不做研究)
size; //当前实际存储键值对的数量
其中threshold = length*loadFactor;当size超过threshold时就进行扩容;
默认loadFactor为0.75