作者:Melody-Zhu1988 | 来源:互联网 | 2023-10-10 03:55
流程首先根据hash方法获取到key的hash值然后通过hash&(length-1)的方式获取到key所对应的Node数组下标(length对应数组长度)首先判断此结点是否为空
流程
- 首先根据 hash 方法获取到 key 的 hash 值
- 然后通过 hash & (length - 1) 的方式获取到 key 所对应的Node数组下标 ( length对应数组长度 )
- 首先判断此结点是否为空,是否就是要找的值,是则返回空,否则进入第二个结点。
- 接着判断第二个结点是否为空,是则返回空,不是则判断此时数据结构是链表还是红黑树
- 链表结构进行顺序遍历查找操作,每次用 == 符号 和 equals( ) 方法来判断 key 是否相同,满足条件则直接返回该结点。链表遍历完都没有找到则返回空。
- 红黑树结构执行相应的 getTreeNode( ) 查找操作。
源码分析
public V get(Object key) {Node<K,V> e;return (e = getNode(hash(key), key)) == null ? null : e.value;
}final Node<K,V> getNode(int hash, Object key) {Node<K,V>[] tab; Node<K,V> first, e; int n; K k;if ((tab = table) != null && (n = tab.length) > 0 &&(first = tab[(n - 1) & hash]) != null) {if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k))))return first;if ((e = first.next) != null) {if (first instanceof TreeNode)return ((TreeNode<K,V>)first).getTreeNode(hash, key);do {if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))return e;} while ((e = e.next) != null);}}return null;
}
remove,put,containsKey 都可以参照 get 的流程,面试的话是没有问题的。put 的话涉及到 - 扩容 和 - 红黑树的升级,remove 会涉及到 - 红黑树的退化,其他流程大体上是一样的。都是获取到 hash 值,根据 hash 值得到数组下标,进行遍历操作。
HashMap知识点总结(附源码分析链接)