Java教程

hashmap源码分析

本文主要是介绍hashmap源码分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

1HashMap的存储结构在JDK1.8中 都做了哪些优化,Node[]数组

JDK7 数组加链表 JDK8 数组加树加红黑树  链表达到8时 并且容量达到64 会将链表,转成红黑树

static final int  TREEIFY_THRESHOLD=8

static final MIN_TREEIFY_CAPACITY=64

//转换链表的临界值 当元素小于此值 会将红黑树转换成链表结构,

static final UNTREEIFY_THRESHOLD=6

红黑树有啥特点?

2Hashmap没有初始容量,默认是多少

static final int DEFAULT_INITIAL_CAPACITY=1<<4//aka 16

  最大值为多少1073741824

static final int MAXIMUN_CAPACITY=1<<30

3加载因子 扩容的阈值

  1. 值是多少,
  2. 为什么是0.75 而不是别的值 出于容量和性能之间平衡的结果,当加载因子设置比较大的时候,扩容的门槛就被提高了,扩容发生的频率就比较低,占用的空间就会比较小,但此时发生Hash冲突的几率就会提升,因此需要更复杂的数据结构来储存元素,这样对元素的操作时间就会增加,运行效率也因此降低。而当加载因子值比较小的时候,扩容的门槛会比较低,因此会占用更多的空间,此时元素的存储就比较稀疏,发生哈希冲突的可能性就比较小,因此操作性能,会比较高,所以综合了以上情况就取了一个0.5到1的平均数0.75作为加载因子。

5什么时候链表转红黑树

链表达到8并且容量达到64时候 链表会转为红黑树

6为什么是2的幂

及时你构造函数时候 不传2的n次方,再后来的初始化方法中,也会强制变成2的n次方

让元素能够快速定位哈希桶,让Hash表元素分布均匀,减少哈希碰撞的几率

7若传入了一个初始化容量,则就是你传入的那个值吗?不一定,

是大于或等于你传入的那个值,离他最仅的那个2的幂的数

8put方法的流程

index:(table.length-1)&hash值 索引的计算公式,寻址公式。

9Node []数组,

   Node的属性有哪些,分别干啥用的

final int hash;final K key ;V value; Node<K,V> next;

10get方法

三种情况:直接数组中命中,需要在树中找,需要在链表中找

11扩容相关

(1)扩容原因

a为了解决哈希冲突导致的链化影响查询效率的问题,扩容会缓解该问题

b容量不够也要扩容

(2)扩容多大

a若原来Node[]就是最大值,不扩

b oldCap左移一位,实现数据翻倍,并且赋值给newCap,newCap小于数组最大值限制,且扩容之前的阈值>=16

12初始化容量一上来就初始化,还是put才初始化?put时候才初始化,跟Arraylist类似

13hashmap线程安全么?不安全 有没有安全的  ConcurrentHashMap

14说一说ConcurrenHashMap原理?

15 HashTable vs HashMap   hashtable比较古老,不用他,他线程安全。

因为hashtable如下 他直接锁方法,对整个数组加锁,力度过大

public synchronized V put(k key,V value)

16 ConcurrentHashMap

采用的是分段锁机制,通过synchronized锁定是代码块。

17 CopyOnWriteArrayList

写时复制容器 它在add方法中使用的是显示锁进行加锁, ReentrantLock

这篇关于hashmap源码分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!