Hashmap核心思想总结

1.Hashmap的用法

haspmap的一般用法如上图,包含key和value。

Q:但是上述的默认用户没有设置容量,hanhmap是如何创建容量的?

A:看Hashmap的源码

这里说,容量必须是2的幂数,然后设置的是左移四位,即16。

Q:为什么会用左移运算(数据都是转换成2进制来读,越接近底层,操作速度会快)

A:Java的底层是C,C的底层是汇编语言,汇编下就是机器语言(2进制),越接近底层效率越高。

Q:为什么是16,而不是4或8?

A:ava的底层是C,C的底层是汇编语言,汇编语言编程使用16进制。联想:Java中的访问修饰符是16进制(ox00001)。

2.Hashmap的核心思想

Hashmap由数组+链表+红黑树(JDK1.8)组成。红黑树是自平衡的二叉树的查找树,其特点之一是:右子树的值比节点大,左子树的值比节点小;

Node是存入Hashmap的类,其结构如下:

Node implement Map.Entry{
    hash
    key
    value
    next
}
Entry{
    K key
    V value
}

Node类实现Entry接口,hash值是根据key值计算出(有个hash算法),next可以联系c++中的链表结构。

Q:如何定位到数组

Hashmap核心思想总结_第1张图片

将key值和value值封装到node对象中,在根据所计算出的hash值和数组(length-1)的值进行位与(&)计算,得到0~length-1之间的索引,即要存入的数组位置。

3.哈希碰撞(冲突)

说明:计算出的索引位置仅与二进制的后四位有关,会有相同的索引值,相同索引值的元素如何存储,就是哈希碰撞问题。

解决方法:

Hashmap核心思想总结_第2张图片

jdk7通过链表解决,当有相同值时就下挂一个链表;jdk8通过红黑树,当下挂元素小于等于6时变为链表;

4.Hashmap的扩容

Q:Hashmap是如何进行扩容操作的,扩容后是如何做到数据均匀分布的?

源码中有关于扩容的方法resize()。

当数组中所占用的容量达到:扩容因子(0.75)*length时,数组的长度会左移一位,即在原长度的基础上增倍。例如,长度为16的hashmap在被占用12个单位时,会扩容成32。

A:通过高位的“奇偶数”解决均匀分布问题,当高位为1时移到索引值为(原索引+length)处,依次判断链表(或红黑树)的高位值,依次重新排布位置,以链表形式举例如下图:

Hashmap核心思想总结_第3张图片

你可能感兴趣的:(学习心得,Java语言)