Interview essential: HashMap underlying data structure? jdk1.8 algorithm optimization, hash conflict, expansion and other issues

Interview series will not be necessary to verify the lengthy theory, the direct answer, for reference only, do not like do not spray.

1, will talk about the principles underlying HashMap do?

HashMap<String,String> map = new HashMap<String,String>(); 

map.put(“key”,”value”); 

[<key1,value1>,<key2,value2>,<key3,value3>] 

+ HashMap underlying implementation list is an array to store the <key, value> in the form of data, when we call put (key, value) , the first key may be acquired by the hash value of hash (key), the hash value of the array length modulo operation, to locate a bucket array storage location, if there is no conflict, then bucket directly into the array, then the conflict list of places stored, after the introduction of jdk1.8 red-black tree, than the length of the list 8 will be used after the red-black tree, and then converted back to less than 6.

2,3 strip are as follows supplement Article 1, prevention fine to ask the interviewer.

2, jdk1.8 optimization algorithm to hash algorithm and addressing

jdk1.8 of the hash algorithm is optimized, prior to when the hash key be (key) is calculated, using the modulo operation, i.e. referred to in Article 1, and is used in addressing the optimized algorithm, namely: (n-1) & hash "n is the length of the array."

Why use algorithms to address it? First " hash & (n-1) " effect with hash modulo n effect is the same, but the performance "&" and the operation is superior to hash modulo n.

3, hash conflict? How to deal with it?

When we put <key, value> , first calculated hash value by the hash (key), and then later by "&" and operation, has been an array of storage locations bucket, but at this time there have been two different key was calculated equal to the bucket, for example:

数组A[0]位置计算出存放<张三,我是张三>数据,而在put<李四,我是李四>数据时,也计算为存放在A[0]位置,一个位置想存放两个数据?这就出现hash冲突了,怎么处理呢?

JDK是这样处理的,它会在这个位置(A[0])挂一个链表,这个链表表里面存放出现冲突的数据,即:让多个<key,value>数据同时放在数组的一个位置里。

get(key)时怎么取呢?当我们调用get(key)定位到数组位置时,如果发现这个位置挂载的是一个链表,那么就遍历链表,从里面找到自己想要的那个<key,value>数据。

格外补充:这个地方,在JDK1.8之后引入了红黑树的概念,首先我们看一下为啥要引入红黑树,如果没有引入红黑树,当数组挂载的链表达到一定长度之后,查询是非常耗时的,性能比较差,时间复杂度为:O(n)「读作:偶en」。

JDK1.8的优化就是,当链表的长度发到了一定长度后(8)会自动转换为红黑树,遍历一棵红黑树查找一个元素的时间复杂度为:O(logn)「读作:偶,老个en」,性能相对链表要高一些。

简单总结一下:

  1. 出现hash冲突的原因?两个不同的key计算出相同的数组存放位置;

  2. 初期是怎么解决的?在出现数组冲突的位置挂一个链表,实现存放多个数据。

  3. JDK1.8的优化?当数组长度达到一定值后自动转换为红黑树,降低时间复杂度。

4、HashMap是如何扩容的?

HashMap底层是一个数组,当数组满了之后,他会自动进行2倍扩容,用于盛放更多的数据。

比如,本来数组默认长度=16,扩容后*2=32。

扩容后还有一步操作:rehash,重新对每个hash值进行寻址,也就是用每个hash值跟新的数组长度 n-1 进行『&』与运算操作。

补充:扩容之后的与运算可能会导致之前的发生hash冲突的元素不再发生冲突。

博客地址:https://www.cnblogs.com/niceyoo

Guess you like

Origin www.cnblogs.com/niceyoo/p/12508024.html