1、put方法
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) { //第1次put时,root为空
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) { //如果比较器存在
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0) //小于就往左边遍历
t = t.left;
else if (cmp > 0) //大于就往右边遍历
t = t.right;
else //相等就重新赋值并返回
return t.setValue(value);
} while (t != null);
}
else { //如果比较器不存在
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value); //相等的key走这里,覆盖
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
//注意:这里只判断大于和小于0两种情况。等于0的情况早已经覆盖新值并返回了。
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e); //红黑树的调整,旋转、变色等
size++;
modCount++;
return null;
}
2、get方法
public V get(Object key) {
Entry<K,V> p = getEntry(key);
return (p==null ? null : p.value);
}
3、getEntry方法
final Entry<K,V> getEntry(Object key) {
// Offload comparator-based version for sake of performance
if (comparator != null)
return getEntryUsingComparator(key);
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
Entry<K,V> p = root;
while (p != null) {
int cmp = k.compareTo(p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
return null;
}
注意:
TreeMap在get一个值得时候,也是如果大于当前节点,则往右边走;反之则往左边走。
总结
1、LinkedHashMap和TreeMap都有顺序。区别是LinkedHashMap是按插入顺序,TreeMap可以自行指定顺序。LinkedHashMap是通过链表保存插入节点。
2、TreeMap可以自行指定顺序,不指定时默认按key的大小进行排序。
3、TreeMap底层就完全是个红黑树了,不再有数组存在了。TreeMap也不是继承于HashMap。
4、LinkedHashMap继承于HashMap,底层还是数组+链表+红黑树结构,只是在put时重写了newNode方法,底层再创建一个双向链表,按顺序接入每一个节点。
5、