Java HashMap详解
什么是Map?
要理解hashMap,首先你要知道什么是map,map是用于存储键值对(<key,value>)的集合类。在java中map是一个接口,是和collection接口同一等级的集合根接口。
map的特点:1、key是无序、唯一的;
2、value是无序不唯一的。
什么是HashMap?
HashMap是用哈希表(数组+单链表)+红黑树实现的map类(JDK1.8之前是数组+单链表,JDK1.8加入了红黑树)。
红黑树实际上就是一个二叉树,只是每个节点都被标记为黑色或者红色。
HashMap初始化
Map map = new HashMap();
HashMap默认初始大小为16。大小只能是2的n次方,若强行给初始大小为非2的n次方,HashMap会自动调整为2的n次方。
HashMap的最大容量为2的30次方,传入容量过大将被这个值替换:
static final int MAXIMUM_CAPACITY = 1 << 30("<<"为左移运算符,1表示十进制中的“1”,30表示十进制数字1转化为二进制后向左移动30位。在数值上等同于2的30次幂)
详解:java中int类型的长度为32位,即2的31次方,由于由于二进制数字中最高的一位也就是最左边的一位是符号位,用来表示正负之分(0为正,1为负),所以最大容量为2的30次方。
HashMap原理
HashMap会将key值取HashCode(一个32位的int型数字),再将此hashCode的高16位与低16位做异或操作,得到最终的hash值,将最终得到的hash值与hashMap的长度减去1做与(&)操作,得到该key-value存放的位置。若出现同一位置,则以链表形式存放,当链表长度大于8时,转换为红黑树存放。
hashCode做高低位异或操作,目的在于打乱Hash值,使得数据尽可能均匀的分布在数组的各个位置。
HashMap扩容
当HashMap的容量达到一定值时,就会进入扩容(resize),HashMap的扩容大小为长度2,及扩大2倍,并将数据重新存放。到达什么值时会进行扩容呢?这里涉及到一个概念,叫负载因子-loadFactor,也就是当haspMap的容量达到HashMap的长度乘以负载因子的值时,就会进入扩容,负载因子的大小为0.75(160.75=12,也就是容量到达12时,就会进入扩容)。
HashMap面试题
1、HaspMap的特性。
1.HashMap存储键值对实现快速存取,允许为null。key值不可重复,value值可重复,若key值重复则覆盖。
2.非同步,线程不安全。
3.底层是hash表,无序存放。
2、谈一下HashMap的底层原理是什么?
JDK1.8之前使用数组+单链表,jdk8后采用数组+链表+红黑树的数据结构。我们通过put和get存储和获取对象。当我们给put()方法传递键和值时,先对键做一个hashCode()的计算来得到它在bucket数组中的位置来存储Entry对象。当获取对象时,通过get获取到bucket的位置,再通过键对象的equals()方法找到正确的键值对,然后在返回值对象。
3、hashMap中put是如何实现的?
1.计算关于key的hash值(对Key.hashCode的高低16位做异或运算,再与size-1做与运算)
2.如果散列表为空时,调用resize()初始化散列表
3.如果没有发生碰撞,直接添加元素到散列表中去
4.如果发生了碰撞(hash值相同),进行三种判断
4.1:若key地址相同或者equals后内容相同,则替换旧值
4.2:如果是红黑树结构,就调用树的插入方法
4.3:链表结构,循环遍历直到链表中某个节点为空,尾插法进行插入,插入之后判断链表个数是否到达变成红黑树的阙值8;也可以遍历到有节点与插入元素的哈希值和内容相同,进行覆盖。
5.如果桶满了(大于阀值),则resize进行扩容
4、hashMap中什么时候需要进行扩容,扩容resize()又是如何实现的?
1.初始化数组table时;
2.当数组table的size达到阙值时,即大于HashMap长度乘以0.75时
扩容需要重新分配一个新数组,新数组是老数组的2倍长,然后遍历整个老结构,把所有的元素挨个重新hash分配到新结构中去。
5、默认容量为什么是16?为什么必须是2的幂?如果输入值不是2的幂比如10会怎么样?
1.为了数据的均匀分布,减少哈希碰撞。因为确定数组位置是用的位运算,若数据不是2的次幂则会增加哈希碰撞的次数和浪费数组空间。
2.输入数据若不是2的幂,HashMap通过一通位移运算和或运算得到的肯定是2的幂次数,并且是离那个数最近的数字
6、当两个对象的hashCode相等时会怎么样?
会产生哈希碰撞,若key值相同则替换旧值,不然链接到链表后面,链表长度超过阙值8就转为红黑树存储
来源:CSDN
作者:日月哥的后花园
链接:https://blog.csdn.net/m0_46189412/article/details/103968563