hashmap学习小结
1.HashMap是基于Map接口实现的一种键-值对<key,value>的存储结构,允许null值,同时非有序,非同步(即线程不安全)。HashMap的底层实现是数组 + 链表 + 红黑树。
2.HashMap定位元素位置是通过键key经过扰动函数扰动后得到hash值,然后再通过hash & (length - 1)代替取模的方式进行元素定位的。
3.HashMap是使用链地址法解决hash冲突的,当有冲突元素放进来时,会将此元素插入至此位置链表的最后一位,形成单链表。当存在位置的链表长度 大于等于 8 时,HashMap会将链表 转变为 红黑树,以此提高查找效率。
4.HashMap的容量是2的n次方,有利于提高计算元素存放位置时的效率,也降低了hash冲突的几率。因此,我们使用HashMap存储大量数据的时候,最好先预先指定容器的大小为2的n次方,即使我们不指定为2的n次方,HashMap也会把容器的大小设置成最接近设置数的2的n次方,如,设置HashMap的大小为 7 ,则HashMap会将容器大小设置成最接近7的一个2的n次方数,此值为 8 。
5.HashMap的负载因子表示哈希表空间的使用程度(或者说是哈希表空间的利用率)。当负载因子越大,则HashMap的装载程度就越高。也就是能容纳更多的元素,元素多了,发生hash碰撞的几率就会加大,从而链表就会拉长,此时的查询效率就会降低。当负载因子越小,则链表中的数据量就越稀疏,此时会对空间造成浪费,但是此时查询效率高。
6.HashMap不是线程安全的,Hashtable则是线程安全的。但Hashtable是一个遗留容器,如果我们不需要线程同步,则建议使用HashMap,如果需要线程同步,则建议使用ConcurrentHashMap。
在多线程下操作HashMap,由于存在扩容机制,当HashMap调用resize()进行自动扩容时,可能会导致死循环的发生。