node = null, e; K k; V v;// 桶上的节点就是要找的keyif (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))// 将Node指向该节点node = p;else if ((e = p.next) != null) { // 链表或者是红黑树节点的情况if (p instanceof TreeNode)// 找到红黑树节点node = ((TreeNode)p).getTreeNode(hash, key);else { // 链表的情况// 遍历链表 , 找到需要找的节点do {if (e.hash == hash &&((k = e.key) == key ||(key != null && key.equals(k)))) {node = e;break;}p = e;} while ((e = e.next) != null);}}// 找到节点之后if (node != null && (!matchValue || (v = node.value) == value ||(value != null && value.equals(v)))) {if (node instanceof TreeNode)// 红黑树remove节点((TreeNode)node).removeTreeNode(this, tab, movable);else if (node == p)// 链表remove , 通过改变指针tab[index] = node.next;elsep.next = node.next;// 记录修改次数modCount;// 变动的数量--size;afterNodeRemoval(node);return node;}}return null;}9、Jdk8中HashMap的get操作get方法:通过key找到value , 这个方法比较容易理解
public V get(Object key) {Node e;return (e = getNode(hash(key), key)) == null ? null : e.value;}final Node getNode(int hash, Object key) {Node[] tab; Node first, e; int n; K k;// 如果哈希表不为空并且key对应的桶上不为空if ((tab = table) != null && (n = tab.length) > 0 &&(first = tab[(n - 1) & hash]) != null) {// 根据索引的位置检查第一个节点if (first.hash == hash && // always check first node((k = first.key) == key || (key != null && key.equals(k))))return first;if ((e = first.next) != null) { // 不是第1个节点的情况 , 那就有可能是链表或者红黑树节点if (first instanceof TreeNode)// 根据getTreeNode获取红黑树节点return ((TreeNode)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;}10、HashMap相关面试题- HashMap的数据结构是什么?
- 在jdk8之前是数组 链表 , jdk8之后是数组 链表 红黑树
- HashMap 中 hash 函数是怎么实现的?
- 先通过jdk的hashCode()方法获取hashCode , 右移16位 , 然后这两个数再做异或运算
- 什么是HashMap中的哈希冲突?
- 哈希冲突 , 也可以称之为哈希碰撞 , 一般是值计算出的哈希值一样的 , 在HashMap中是根据计算出的hash , 再去计算数组table下标(n-1)&hash一样了 , 也就是冲突了
- HashMap是如何处理哈希冲突问题的?
- 在jdk8之前是通过链表的方法 , jdk8之后是通过链表 红黑树的方法
- HashMap是线程安全的?
- HashMap不是线程安全的 , 因为源码里没加同步锁也没其它保证线程安全的操作
- HashMap不是线程安全的 , 然后有什么方法?
- 可以使用ConcurrentHashMap
- ConcurrentHashMap是怎么保证线程安全的?
- ConcurrentHashMap在Jdk8中 使用了CAS加上synchronized同步锁来保证线程安全
推荐阅读