参考:https://segmentfault.com/a/1190000012926722
总结:
1.hashmap特性?
(1)存取键值对 (2)允许null的键/值 (3)非同步 (4)不保证有序
2.hashmap的原理?
底层使用数组+链表+红黑树来实现,两个重要方法put,get分别用来存取对象
(1)put方法
1.调用hashcode计算hash值,然后对hash值进行运算[ (n - 1) & hash ],得到对应的bucket位置,然后存储Entry对象。hashmap也会根据当前bucket的占用情况自动调整容量
2.如果没碰撞直接放到bucket里;
3.如果碰撞了,以链表的形式存在buckets后;
4.如果节点已经存在就替换old value(保证key的唯一性)
5.如果bucket满了(超过阈值,阈值=loadfactor*current capacity,load factor默认0.75),就要resize。
(2)get方法,通过对key的hashCode()进行hashing,并计算下标( n-1 & hash),从而获得buckets的位置。如果产生碰撞,则 利用key.equals()方法去链表中查找对应的节点。
(3)如果一个bucket中碰撞冲突的元素个数超过8,则使用红黑表来替换链表,从而提高速度(复杂度由On变为Ologn)
3.HashMap怎样解决冲突?
链地址法(内部数据结构就是 数组+单链表)
(关于哈希冲突的解决办法还有:开放地址法,再哈希法)
4.hashmap和hashtable的区别?
(1)继承的父类不同。AbstractMap和dictionary
(2) 线程安全不同,hashmap不是线程安全,hashtable线程安全
(3)是否提供contains方法,hashmap不提供contains方法而改成了containsValue和containskey避免误解
(4)key和value是否允许null,前者允许(key为null时放在table[0]),后者不允许。
(5)hash值不同,hashtable直接使用对象的hashcode(),而hashmap重新计算hash(key.hashCode()) ^ (h >>> 16))
(6) 初始化和扩容方式不同,hashtable默认容量11.hashmap16