1.HashMap的底层实现原理?
HashMap的底层是数组+链表的方式,通过Hash算法决定每个元素的存储位置,当程序执行map.put()方法时,系统会调用hashcode()方法来得到他的hash值,通过hash值来确定该元素的存储位置,如果该位置没有元素即直接存储,如果已经有了,就存在两个两种情况,1.hashcode相同,key相同,则直接覆盖原来的值,2如果hash值相同,key不同,则把新元素加到entry链条当中去。也可以说数组为了让查询更快,链表是为了解决hash冲突。
2.Hashmap是怎么解决hash冲突的?
冲突的产生是由于不同对象的hashCode()方法返回了一样的值。这就导致存储位置会一样,于是HashMap通过链地址法使相互碰撞的所有value形成一个链表。在jdk1.8之后做了改进,用常量TREEIFY_THRESHOLD来控制是否切换到平衡二叉树来存储,目前,这个常量值是8,这意味着当有超过8个元素的索引一样时,HashMap会使用树来存储它们。
3.HashMap什么进行扩容呢?
HashMap默认的加载数组大小为16,加载因子的默认值为0.75,当HashMap中元素的个数超过16*0.75=12时,就会把数组大小扩大为原来的一倍。然后重新计算每个元素在数组当中的位置(扩容是需要复制,复制是非常耗能,如果能预知容量大小,并且才创建对象预设元素个数,可以提高HashMap的性能。)
4.如何保证HashMap的现场安全?
HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。
Map map = Collections.synchronizedMap(new HashMap());