TreeMap是一种实现了有序的Map类型。
TreeMap基于红黑树原理实现。
TreeMap是线程不安全的。
TreeMap实现了 NavigableMap<K,V>接口支持导航方法,TreeMap继承自AbstractMap<K,V>。
put方法原理
1、判断有没有root节点。没有则创建一个root(节点用new Entry<K,V>)表示。modCount++
2、定义一个父节点parent记录节点搜索路径,一个比较记录cmp
3、判断比较器是否存在,不存在则使用默认比较器Comparable对Key进行装饰。key直接调用比较方法。
4、根据比较结果沿左子树和右子树遍历节点,得到与key相等的节点,执行setValue方法。
5、如果一直没有找到节点,因为parent记录了t的搜索路径,所以new Entry<K,V>(key, value, parent),构造新的Entry节点,挂载到parent。
put方法源码
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
*
* @return the previous value associated with <tt>key</tt>, or
* <tt>null</tt> if there was no mapping for <tt>key</tt>.
* (A <tt>null</tt> return can also indicate that the map
* previously associated <tt>null</tt> with <tt>key</tt>.)
* @throws ClassCastException if the specified key cannot be compared
* with the keys currently in the map
* @throws NullPointerException if the specified key is null
* and this map uses natural ordering, or its comparator
* does not permit null keys
*/
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
// TBD:
// 5045147: (coll) Adding null to an empty TreeSet should
// throw NullPointerException
//
// compare(key, key); // type check
root = new Entry<K,V>(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();
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);
} while (t != null);
}
Entry<K,V> e = new Entry<K,V>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}