HashMap复习时候的一些问题总结
在获取hash值的时候,为什么要对hashcode进行一个右移16位的操作
1 | static final int hash(Object key) { |
答: 目的是为了将hashcode的高位和低位进行混合,从而减少hash冲突的发生,也只能降低hash冲突的可能,增加性能.
为什么hash冲突会影响性能
因为hashmap最好的性能是实现O1的查找,插入,删除效率,但是由于会出现hash冲突,会导致多个值被装进同一个桶中,在hashmap里面桶里面的数据结果是用链表,红黑树来实现的,链表和红黑树的插入删除查找的复杂度增加了,就导致了hashmap的效率降低了.
为了减少hash冲突,应该选择合适的hash函数.调整hash表的大小,调整合适的装载因子.
hashmap里面默认的装载因子是0.75.
扩容发生在哪些情况
- 当hashmap里面的所有键值对的数量超过了设置的hashmap容量(默认大小16),时候会发生扩容
什么情况下会转换成红黑树
当单个桶的数量超过8的时候:
1 | int TREEIFY_THRESHOLD = 8; |
线程安全的话使用谁比较好
首先需要知道HashMap不是线程安全的.
线程安全的有:
- HashTable
- ConcurrentHashMap
HashTable : 实现的线程安全很简单,他直接给 put get 方法进行上锁(synchronized).这就导致在插入获取数据的时候效率会降低.
ConcurrentHashMap : 他在获取数据的时候效率比HashTable高,因为 get操作是不加锁的,他用了 volatile 关键字进行修饰,这个关键字保证了有序性和可见性,保证了每次获取的数据都是最新的.然后在 put 的时候使用乐观锁实现同步问题.