前言
了解hashmap.get(O)方法之前,首先要先了解下内部的数据结构
时间复杂度
从上图可以看出,table[index]元素存在四种情况
tanble[index] 是 null 时 时间复杂度是 O1
tanble[index] 是 单个Node对象 时 时间复杂度是 O1
tanble[index] 是 Node链表 时 时间复杂度是 On
tanble[index] 是 TreeNode红黑树 时 时间复杂度是 Ologn
源码
get(Object key)获取value
//获取最重要的方法是getNode(hash(key)
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
getNode(hash(key), key)获取Node
final Node<K,V> getNode(int hash, Object key) {
Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
//判断数组或者数组table[index]种数据不为null
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;
}
getTreeNode(int h, Object k) 从红黑树种查找
final TreeNode<K,V> getTreeNode(int h, Object k) {
//从根节点开发向下查找
return ((parent != null) ? root() : this).find(h, k, null);
}
find(int h, Object k, Class<?> kc)
final TreeNode<K,V> find(int h, Object k, Class<?> kc) {
//拿到整棵树
TreeNode<K,V> p = this;
do {
int ph, dir; K pk;
TreeNode<K,V> pl = p.left, pr = p.right, q;
//如果h小于p.hash,那么需要在p的left节点接着查找
if ((ph = p.hash) > h)
p = pl;
else if (ph < h)
//从p的right节点查找
p = pr;
else if ((pk = p.key) == k || (k != null && k.equals(pk)))
//找到了直接返回
return p;
//做了兼容
else if (pl == null)
p = pr;
else if (pr == null)
p = pl;
//找出比较器
else if ((kc != null ||
(kc = comparableClassFor(k)) != null) &&
(dir = compareComparables(kc, k, pk)) != 0)
p = (dir < 0) ? pl : pr;
//再次查找
else if ((q = pr.find(h, k, kc)) != null)
return q;
else
p = pl;
} while (p != null);
return null;
}
有了put和get源码的了解,像其他方法就比较简单了,有兴趣的看下实现方式,大部分内容put方法里面已经涵盖了