1.hashMap的原理,是如何实现的?线程安全问题? hashmap如何实现动态扩容?
(1)实现原理
HashMap是基于散列法(又称哈希法hashing)的原理,使用put(key,value)存储对象到HashMap中,使用get(key)从HashMap中获取对象。当给put()方法传递键和值时,我们先对键调用hashCode()方法,根据返回的hashCode用于找到bucket(桶)位置来储存Entry对象。”HashMap是在bucket中储存键对象和值对象,作为Map.Entry。并不是仅仅只在bucket中存储值。
(2)hashmap并不是线程安全的,但是 ConcurrentHashMap、HashTable是线程安全的。
2.hashmap和hashtable区别
(1)都是map的实现类、都是键值对集合
(2)里边的元素都是无序的,跟添加顺序无关。
(3)HashMap允许多个null值和一个null键,HashTable不允许有null值和null键
(4)HashTable是线程安全的,HashMap不是线程安全的
3.HashMap存在大量哈希冲突该怎么处理?
(1)hash冲突:如果键值的hashcode相同,它们的存储位置就相同。如果key不同,那么就会产生hash冲突。这时HashMap的单个bucket里存储的不是一个 Entry,而是一个 Entry 链。
如果存在相同的hashcode和相同的key的元素,那么新值覆盖原来的旧值,并返回旧值。
(2)如果要查找数据,只能按顺序遍历每个 Entry链
4.伪造hash冲突现象——形成单链表
(1)因为HashMap的初始大小16,但是我在hashmap里面放了超过16个元素,并且我屏蔽了它的resize()方法,不让它去扩容。这时HashMap的底层数组Entry[] table结构如下:
5.hashMap大小及扩容(基于内部实现机制)
(1)阈值threshold=DEFAULT_LOAD_FACTOR因子*DEFAULT_INITIAL_CAPACITY大小(16)
(2)通过ReHash进行扩容,调用resize方法。
(3)负载因子默认0.75,减小负载因子,增加hash表所占的内存空间,提高数据的查询性能
6.如何解决散列值的冲突问题?
(1)链表法:将相同hash值对象组成一个链表放在hash值对应的位置;
(2)开放地址法:通过探测算法,如果某个槽位被占据,就查找下一个可以使用的槽位。