一、HashMap底层
1.HashMap的实现原理及应用场景?
2.HashMap存在大量Hash冲突怎么办?如何伪造Hash冲突?
3.HashMap大小、如何实现动态扩容,什么时候ReHash?
4.HashMap改变所占的内存空间?改变数据查询性能(改变哈希因子)?
5.如何实现线程安全的HashMap?
-----------------------------------------------------------------------------------------------------------------------------
一、实现原理及应用场景?
1.实现原理?
(1)HashMap是基于散列法(又称哈希法hashing)的原理,使用put(key,value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。
(2)当给put()方法传递键和值时,我们先对键调用hashCode()方法,根据返回的hashCode用于找到bucket(桶)位置来储存Entry对象。”HashMap是在bucket中储存键对象和值对象,作为Map.Entry。并不是仅仅只在bucket中存储值。
二、哈希冲突?HashMap中如何解决哈希冲突?如何伪造hash冲突?如果2个键的hashcode相同,如何获取对象?
1.哈希冲突?
HashMap中主要是通过key值来计算HashCode值,如果hash值相同就会出现hash碰撞;
2.如何解决散列值冲突问题?
(1)链表法:HashMap底层是通过链表来解决hash冲突的,使用LinkedList存储对象(存储位置一般为hash(key)%len),这时bucket里边存储的不是一个Entry,而是一个Entry链;
(2)开放地址法:通过探测算法,如果某个槽位被占据,就查找下一个可以使用的槽位。
3.如何伪造hash冲突?
(1)因为HashMap的初始大小16,在hashmap里面放了超过16个元素,并且屏蔽它的resize()方法,不让它去扩容。这时HashMap的底层数组Entry[] table结构如下:
4.2个hashcode值相同时如何取对象?
首先根据键对象的hashcode找到bucket位置,然后根据keys.equals()方法去找LinkedList中正确的节点对象。
三、HashMap大小,如何实现动态扩容,什么时候ReHash?
1.HashMap默认大小为16
2.如何实现动态扩容、何时Rehash,?
(1)默认负载因子为0.75,当map填满了75%的bucket时,需要进行扩容,这个时候就会进行rehash操作,当size达到threshold时会调用resize函数进行扩容;
(2)将会创建2倍HashMap大小的bucket数组,并将原来的对象放入新的bucket数组中。
四、HashMap改变所占的内存空间?改变数据查询性能(改变哈希因子)?
1.HashMap改变所占的内存空间?改变数据查询性能(改变哈希因子)?
负载因子默认0.75,减小负载因子,增加hash表所占的内存空间,提高数据的查询性能。