两种方法:
- 引用类型实现comparable重写compareTo方法
- 构造函数中new Comparator,匿名内部类,重写compare 方法。
两种方法均可以在源码中发现
/**
* 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 {@code key}, or
* {@code null} if there was no mapping for {@code key}.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with {@code key}.)
* @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) {
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;
//这里使用构造方法时传入的Comparator进行比较
if (cpr != null) {
do {
parent = t;
//compare的方法入参,第一个参数为待插入的数值,第二个参数为已经存在的数值
cmp = cpr.compare(key, t.key);
//计算的值小于0,往左子树方向遍历
if (cmp < 0)
t = t.left;
//计算的值大于0,往右子树方向遍历
else if (cmp > 0)
t = t.right;
//当计算的值等于0,程序判断这个数时已经存在的,即执行修改操作
else
return t.setValue(value);
//t!=null即找到一个空节点进行存放
} while (t != null);
}
//这里使用定义在类上面实现Comparable接口的compareTo()方法进行排序
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);
} while (t != null);
}
//上面的排序完成,会找到一个空节点,它的父节点是parent,再根据排序值判断,是插入左子树还是插入右子树
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
//这里进行节点的调整和插入(左倾/右倾)
fixAfterInsertion(e);
size++;
modCount++;
return null;
}