HashMap的读流程其实就是get方法,如下:
get的具体步骤:
①.指定key通过hash函数得到key的hash值,int hash=key.hashCode();
②.调用内部方法getNode(),得到桶号(一般为hash值对桶数求模)
int index=hash%Entry].length;
jdk1.6版本后使用位运算替代模运算,int index=hash&(Entry].length-1);
③.比较桶的内部元素是否与key相等,若都不相等,则没有找到。相等,则取出相等记录的value。
④.如果得到key所在的桶的头结点恰好是红黑树节点,就调用红黑树节点的getTreeNode()方法,否则就遍历链表节点。getTreeNode方法使通过调用树形节点的find()方法进行查找。由于之前添加时已经保证这个树是有序的,因此查找时基本就是折半查找,效率很高。
⑤.如果对比节点的哈希值和要查找的哈希值相等,就会判断key是否相等,相等就直接返回;不相等就从子树中递归查找。
jdk1.7读流程:
1.key是否为空值null,如果为空,直接遍历table0]链表,寻找key==null键。调用的是getForNullKey()方法。如下:
1.1.如果元素个数为0,直接返回null。
1.2.遍历table0]。
1.3.遍历到了,返回值;没遍历到,返回null。
2.key不为空,获取entry。调用getEntry方法。
2.1.如果元素个数为0,直接返回null。
2.2.计算hash。如果key为null,hash值是0;如果不为0,调用hash()方法。
2.3.计算索引位置。调用indexFor()方法。
2.4.遍历table索引]。哈希相等,key相等(【==相等】或者【key不为空并且equals()相等】),这种情况就算找到了。
2.5.遍历到了,返回值;没遍历到,返回null。
3.如果entry为空,返回空;如果entry不为空,返回entry的value值。
jdk1.8读流程:
1.计算哈希。调用hash()方法。
2.调用getNode()方法获取node对象。
2.1.table数组已经初始化,长度大于0,根据hash寻找table中的项也不为空。
2.2.table索引]中的first元素的key相等,直接返回node;不相等,执行下一步骤2.3。
2.3.如果first元素的next节点存在,继续下一步骤2.4。
2.4.如果first元素是TreeNode,调用getTreeNode()方法。
2.4.1.获取root节点。
2.4.2.调用find方法,获取TreeNode对象。
2.5.如果first元素不是TreeNode,遍历链表。
3.如果node对象为空,直接返回null;如果不为空,返回e.value。