public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap<K,V>{
//外置比较器
private final Comparator<? super K> comparator;//null
//根节点
private transient Entry<K,V> root;//0x001
//元素的个数
private transient int size = 0;//3
//外部操作数(记录添加和删除的次数)
private transient int modCount = 0;//3
//使用无参构造创建TreeMap时,外置比较器为null
public TreeMap() {
comparator = null;
}
//使用有参构造创建TreeMap时,外置比较器不为null
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
//key - new Student("水菜丽", '女', 21, "2401", "003")
//value - "写代码"
public V put(K key, V value) {
//t - 0x001
Entry<K,V> t = root;
//第一次添加元素时进入的判断
if (t == null) {
compare(key, key); // null对象的检测,如果key是为null,会报空指针异常
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
//比较结果
int cmp;
//父节点
Entry<K,V> parent;
//获取外置比较器对象
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();
//t - 0x003
//Comparable<? super K> k = new Student("水菜丽", '女', 21, "2401", "003")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
//parent - 0x003
parent = t;
//k - new Student("水菜丽", '女', 21, "2401", "003")
//t.key - new Student("水菜丽", '女', 21, "2401", "003")
cmp = k.compareTo(t.key);//21-21 --> 0
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
//e - 0x003
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;
}
//k1 - new Student("椎名空", '女', 23, "2401", "002")
//k2 - new Student("椎名空", '女', 23, "2401", "002")
@SuppressWarnings("unchecked")
final int compare(Object k1, Object k2) {
return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
: comparator.compare((K)k1, (K)k2);
}
//映射关系类/节点类
static final class Entry<K,V> implements Map.Entry<K,V> {
K key; ------------------ 键
V value; ---------------- 值
Entry<K,V> left; -------- 左边节点的地址
Entry<K,V> right; ------- 右边节点的地址
Entry<K,V> parent; ------ 父节点的地址
boolean color = BLACK; -- 默认黑数
Entry(K key, V value, Entry<K,V> parent) {
this.key = key;
this.value = value;
this.parent = parent;
}
//value - 写代码
public V setValue(V value) {
//oldValue = 0x003.value -> 打游戏
V oldValue = this.value;
//0x003.value = "写代码"
this.value = value;
return oldValue;//返回被替换的value
}
}
}
场景1:
TreeMap<Student,String> map = new TreeMap<>();
map.put(new Student("椎名空", '女', 23, "2401", "002"),"看书");
map.put(new Student("麻生希", '女', 27, "2401", "001"),"运动");
map.put(new Student("水菜丽", '女', 21, "2401", "003"),"打游戏");
map.put(new Student("水菜丽", '女', 21, "2401", "003"),"写代码");
场景2:
TreeMap<Student,String> map = new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if(o1.equals(o2)){
return 0;
}
int nameLen1 = o1.getName().length();
int nameLen2 = o2.getName().length();
if(nameLen1 != nameLen2){
return Integer.compare(nameLen1, nameLen2);
}
int age1 = o1.getAge();
int age2 = o2.getAge();
if(age1 != age2){
return Integer.compare(age1, age2);
}
return 1;
}
});
map.put(new Student("椎名空", '女', 23, "2401", "002"),"看书");
map.put(new Student("麻生希", '女', 27, "2401", "001"),"运动");
map.put(new Student("水菜丽", '女', 21, "2401", "003"),"打游戏");
map.put(new Student("水菜丽", '女', 21, "2401", "003"),"写代码");
注意:TreeMap的数据结构是红黑树(平衡二叉树)
红黑树的概念:
- 根节点左右两边的级数不能超过1
- 根节点到任意的叶子节点的黑数个数是一样的
红黑树的优点:查询快
红黑树的区别:添加和删除慢