HashMap原理

Java面试题

HashMap原理

 HashMap是数组+链表/红黑树结构,在put元素时会经过以下步骤:

1.先根据key的hashcode计算存储索引。

2.如果数组为空,则先执行resize进行扩容。

3.判断是否存在哈希冲突,如果没有则直接生成链表结构Node放入对应数组下标。

4.如果存在哈希冲突,判断对应下标元素是红黑树结构时,则直接在红黑树上新增数据。

5.如果存在哈希冲突,同时对应下标元素是链表结构时,则通过尾插法将数据插入到链表中。插入后通过链表长度以及数组长度来判断是否转换为红黑树结构。

6.最后当数组长度大于扩容阈值时,则执行resize进行扩容。

HashMap的数据结构

        数组+链表/红黑树,HashMap本质是个Node数组,每个数组元素是链表或红黑树结构。当链表长度超过8并且map中超过64个元素时,会转成红黑树结构,以提升查询效率。(引用链表时间复杂度是O(n),而红黑树时间复杂度为O(logn))

索引计算

计算key的hash值:当key为null时,则返回0,否则取key的hashcode的高16位异或低16位实现。

索引值:使用key的hash值与当前map中数组的长度-1进行相与操作。得到此数据应放入数据的索引值。

扩展:

因为数组长度总是2的n次方,所以计算索引值时,使用hash值与数组长度length-1相与等价于hash%length取余操作,位运算&比%有更高效率。

为什么在解决 hash 冲突的时候,不直接用红黑树?而选择先用链表,再转红黑树?

链表结构查询效率低,插入效率很高,红黑树查询效率高,但是插入时需要进行左旋、右旋、变色来保持树结构平衡,所以插入效率低。而当元素少时,链表结构查询效率已经足够满足使用性能要求。

HashMap 和 HashTable 有什么区别?

1.HashMap是线程不安全的,HashTable是线程安全的(方法用synchronized修饰来保证线程安全)。

2.HashMap效率比HashTable高。

3.HashMap允许key或value为null,HashTable中key或value都不允许null。

4.HashMap默认初始化数组大小为16,扩容时增大到两倍,HashTable为11,扩容时为两倍+1.

你可能感兴趣的:(Java面试题,面试,java)