扫码关注公众号

容器和Map之 Map 1.7和1.8
03-18
303观看
01

HashMap的底层数据结构是什么?

在JDK1.7和JDK1.8中有所差别:在JDK1.7中,由“数组+链表”组成,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。在JDK1.8中,由“数组+链表+红黑树”组成。当链表过长,则会严重影响HashMap的性能,红黑树搜索时间复杂度是O(logn),而链表是糟糕的O(n)。因此,JDK1.8对数据结构做了进一步的优化,引入了红黑树,链表和红黑树在达到一定条件会进行转换:当链表超过8且数据总量超过64才会转红黑树。将链表转换成红黑树前会判断,如果当前数组的长度小于64,那么会选择先进行数组扩容,而不是转换为红黑树,以减少搜索时间。

来自:容器和Map-Map 1.7和1.8
02

说一下HashMap 的put方法流程?

首先根据key的值计算hash值,找到该元素在数组中存储的下标;如果数组是空的,则调用resize进行初始化;如果没有哈希冲突直接放在对应的数组下标里;如果冲突了,且key已经存在,就覆盖掉value;如果冲突后,发现该节点是红黑树,就将这个节点挂在树上;如果冲突后是链表,判断该链表是否大于8,如果大于8并且数组容量小于64,就进行扩容;如果链表节点大于8并且数组的容量大于64,则将这个结构转换为红黑树;否则,链表插入键值对,若key存在,就覆盖掉value。

来自:容器和Map-Map 1.7和1.8
03

说一下HashMap 1.7和1.8的区别

1结构区别:HashMap1.8的底层数据结构是数组+链表+红黑树。HashMap1.7的底层数据结构是数组加链表。2扩容的区别:Jdk1.7:头插法,添加前先判断扩容,当前准备插入的位置不为空并且容量大于等于阈值才进行扩容,是两个条件!扩容后可能会重新计算hash值。Jdk1.8:尾插法,初始化时,添加节点结束之后和判断树化的时候都会去判断扩容。我们添加节点结束之后只要size大于阈值,就一定会扩容,是一个条件。由于hash是final修饰,通过e.hash&oldCap==0来判断新插入的位置是否为原位置。

来自:容器和Map-Map 1.7和1.8
课程
专栏
【校招VIP】大厂面试题:JDK1.7和1.8的HashMap有哪些区别
csdn
HashMap
【校招VIP】JDK1.7和JDK1.8中HashMap为什么是线程不安全的?
csdn
HashMap
jdk
【校招VIP】HashMap精选面试题
HashMap 的核心面试题
知乎
HashMap
面试题
java语言-容器和Map-Map 1.7和1.8
3专栏
1课程
3 试题