啥都不会就翻译下代码吧
- 先分析HashMap的get方法
- 先查看get方法体
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
3.在查看getNode方法体 我看代码注释 水平有限仅供参考
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) {
//1、判斷 table數組是否為空
//2、判斷 table的長度大於0
//3、判斷 0至table,length-1與hash值後的數組地址 一般來說是鏈錶頭或者是樹的頂部不為空
if (first.hash == hash && // always check first node
((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;
}
- 接下来看((TreeNode<K,V>)first).getTreeNode(hash, key)的方法体
/**
* Calls find for root node.
*/
final TreeNode<K,V> getTreeNode(int h, Object k) {
return ((parent != null) ? root() : this).find(h, k, null);
}
其中root方法去找了树顶 并返回了值
final TreeNode<K,V> root() {
for (TreeNode<K,V> r = this, p;;) {
if ((p = r.parent) == null)
return r;
r = p;
}
}
- 查看find方法 盲猜是遍历树然后找到符合的key的TreeNode返回
/**
* Finds the node starting at root p with the given hash and key.
* The kc argument caches comparableClassFor(key) upon first use
* comparing keys.
*/
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;
if ((ph = p.hash) > h)
//1、ph 賦值為當前P的hash值
//2、如果大於輸入的hash值 則p賦值為樹的左葉 從樹左邊開始找
p = pl;
else if (ph < h)
//1、如果小於輸入的hash值 則p賦值為樹的右葉 從樹右邊開始找
p = pr;
else if ((pk = p.key) == k || (k != null && k.equals(pk)))
//pk賦值為p.key
//如果當前p的key相等於輸入k 或者是 k不為空並且k與當前p.key的equal方法成立就是找到了值返回p即可
//這裡有個疑惑k是Object的equal方法還是泛型類K的equals方法
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)
//kc是null
//只有当传入对象的运行时类型符合”class C implements Comparable”这个条件时,返回对象的运行时类型,否则返回null。
//假設key是String 其實實現了這個接口 然後返回一個String.class
//如果pk不為空 並且 pk.getClass()等於kc(String.class) 然後返回k和pk的compareTo結果賦值給dir
//如果上述條件不成立不進來這裡
p = (dir < 0) ? pl : pr;//如果dir小於0則左邊繼續 否則右邊繼續(右邊有個0的情況)
else if ((q = pr.find(h, k, kc)) != null)
//右邊樹葉繼續找
return q;
else
//到這裡我已經混亂了 什麼情況會出現這裡
//如果以上條件都不滿足默認去左邊找
p = pl;
} while (p != null);
//沒找到返回空
return null;
}
这里要把引用的地址贴一下 这一段是别人的生产结果我也是引用一下
static Class<?> comparableClassFor(Object x) {
if (x instanceof Comparable) { // 判断是否实现了Comparable接口
Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
if ((c = x.getClass()) == String.class)
return c; // 如果是String类型,直接返回String.class
if ((ts = c.getGenericInterfaces()) != null) { // 判断是否有直接实现的接口
for (int i = 0; i < ts.length; ++i) { // 遍历直接实现的接口
if (((t = ts[i]) instanceof ParameterizedType) && // 该接口实现了泛型
((p = (ParameterizedType)t).getRawType() == // 获取接口不带参数部分的类型对象
Comparable.class) && // 该类型是Comparable
(as = p.getActualTypeArguments()) != null && // 获取泛型参数数组
as.length == 1 && as[0] == c) // 只有一个泛型参数,且该实现类型是该类型本身
return c; // 返回该类型
}
}
}
return null;
get方法就分析到这里仅仅把看到的代码贴一下,还有很多不懂得地方 希望大家帮忙答疑