HashMap,2025年了,没想到还要复习这玩意儿。java已死!!!!

32 阅读2分钟

hashmap的结构和原理

简单一句话就是数组+链表+红黑树。

思考:

1.为什么不是数组就行了?为什么要这么复杂的结构?

因为这个结构就是为了查询、修改、删除数据的时候性能更好。

2.这个链表多长的时候要转换成红黑树?

根据泊松分布,概率等原因,取了平衡值8,当达到这个值就会转换成红黑树。

3.为什么要用红黑树?用平衡二叉树不行吗?

主要是因为平衡二叉树维护起来的开销会比较大,所以经过权衡选择的这个。

4.那么当数据删除的时候,节点数变成多少的时候会退化成链表?

这个值是6,为什么不是8,因为需要防止抖动,万一频繁的插入和删除,那么就会不断地转换红黑树和退化,这样性能更差。

5.这个数组的初始值是多大?

16,这个是一个2的幂次方,数值是通过hash&(N-1)计算知道自己存放的位置的。

6.hashmap的扩容机制?

有一个关键的参数,叫加载因子,是用来衡量hashmap的拥挤程度的。java的hashmap默认加载因子是0.75。公式:阈值 = 数组容量 * 加载因子。当达到这个阈值的时候就会触发扩容,扩容一倍,从开始的16到32,那么之前的数据都要重新hash和重新索引。

7.触发扩容机制是不是会越来越慢?并且数据越大越明显

其实是java里面做了优化,扩容之后,重新hash计算的话,公式里面的N-1一直会是K个1,比如:N=16,N-1=15,二进制是1111,N=32,N-1=31,二进制是11111,然后hash值的这位数如果是0,那么这位数最后的结果就是0,就是原来的数字了,如果是1,那么计算完就是1,刚好这个数就是原先的数+扩容的数。总结就是,扩容之后,原先的值经过计算要么就是还在原来的位置,要么就是原来的位置+扩容的数。

8.红黑树的原理是什么?

首先,满足红黑树需要5个条件,1:节点的颜色要么是红色,要么是黑色。2.根节点永远是黑色。3.所有的街子节点(NIL节点,即空节点)都是黑色的 4.如果一个节点是红色的,那么他的两个子节点必须是黑色的(不能有两个连续的红色节点)5.从任一节点到其所有后代叶子节点的简单路径上,包含的黑色节点数量必须相同

开放式思考:如果重新设计这个hashmap,你觉得应该怎么设计更加高效?