HashMap的get方法是通过key获取对应Value的方法,resize方法则是初始化或扩容数组的方法,来看看是如何实现的;

1.get方法




java 数组 查找下标 java数组根据下标获取数据_赋值


通过getNode方法传入key的hash值与key,判断返回是否为空,空则返回null,否则返回key对应的value值;


java 数组 查找下标 java数组根据下标获取数据_链表_02


方法中第一个if判断数组是否为空、数组长度是否大于0,并且通过(n-1)&hash计算出的下标在数组中是否存在元素,满足以上条件则,进入第二个if判断,拿到下标所在的元素的hash值与传入的hash值进行比较,如果相等并且key值也相等,则命中元素直接返回;如果没有命中,则进入下一个if判断看下标元素的next是否有值,如果有判断当前元素是否为红黑树,如果为红黑树则通过hash值、key值在树中获取元素返回;否则就是链表,然后循环链表,直到hash与key都相等则命中,否则返回null;

2.resize方法


java 数组 查找下标 java数组根据下标获取数据_数组_03


resize方法的作用是扩容,方法较长我们分前后两个部分进行分析,前半部分比较简单,首先看定义的这几个变量,oldCap:老容量,oldThr:老阈值,newCap:新容量,newThr:新阈值,oldTable就是当前的数组;然后第一个if判断,oldCap是否大于0,大于0说明是扩容,否则说明数组第一次初始化容量,满足条件进入内部判断容量是否大于等于最大容量,满足条件则给阈值赋值为最大int,然后返回;否则老容量扩大二倍赋值给新容量,老阈值扩大2倍给新阈值;


java 数组 查找下标 java数组根据下标获取数据_数组_04


这显然是初始化的时候,赋值新容量为16,新阈值为16*0.75=12;


java 数组 查找下标 java数组根据下标获取数据_数组_05


创建一个大小为新容量的Node数组并赋值给数组,这时候并发查询会出问题;


java 数组 查找下标 java数组根据下标获取数据_通过数组下标获取值都有哪些方法_06


这段代码主要是遍历老的数组,判断元素类型是普通Node、链表、红黑树,如果是普通Node元素则通过hash&(newCap-1)计算出新下标并赋值,如果是红黑树解析赋值给新数组;如果是链表,则根据hash&oldCap的算法区分是高位还是低位,如果是低位下标不变,如果不为0则说明hash值大于老数组长度,应该放到高位上;


java 数组 查找下标 java数组根据下标获取数据_java 数组 查找下标_07


第一个判断说明低位的元素链表还放到原来的位置,第二个判断说明高位的元素放在原有位置偏移了老数组长度的位置;