TreeSet 源码解读
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSet01 {
@SuppressWarnings({"all"})
public static void main(String[] args) {
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//下面 调用String的 compareTo方法进行字符串大小比较
// return ((String)o2).compareTo((String)o1);
//要求加入元素,按照长度大小排序
return ((String)o2).length() - ((String)o1).length();
}
});
treeSet.add("Jack");
treeSet.add("Rose");
treeSet.add("CiCi");
treeSet.add("XiXi");
treeSet.add("XiXi"); //不可添加重复元素
System.out.println(treeSet);
}
}
/*
运行结果(进行字符串大小比较):
[XiXi, Rose, Jack, CiCi]
运行结果(按照长度大小排序):
[Jack]
源码解读:
1.构造器把传入的比较器对象,赋给了 TreeSet 的底层的 TreeMap 属性的 this.comparator
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
2.在用 treeSet.add("tom"),底层会执行到
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;
if (cpr != null) { //cpr 就是我们的匿名内部类(对象)
do {
parent = t;
//动态绑定到我们的匿名内部类(对象)compare
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else //如果相等,即返回零,这个key就没有加入了
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);
} while (t != null);
}
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;
}
*/
TreeMap 源码解读
import java.util.Comparator;
import java.util.TreeMap;
public class TreeMap01 {
public static void main(String[] args) {
//使用默认的构造器,创建TreeMap,是无序的(也没有排序)
// TreeMap treeMap = new TreeMap();
TreeMap treeMap = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//按照传入数据的大小进行排序
// return ((String)o1).compareTo((String)o2);
//按照传入数据的长度进行排序,相同长度只会输入一个,就是相同第一个添加的
return ((String)o1).length() - ((String)o2).length();
}
});
treeMap.put("Rose",8);
treeMap.put("Jack",1);
treeMap.put("Tom",2);
treeMap.put("CiCi",3);
treeMap.put("Rose",4);
System.out.println(treeMap);
}
}
/*
源码解读:
1. 构造器,把传入的实现了 Comparator 接口的匿名内部类(对象),传给TreeMap的comparator
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
2.调用put方法
2.1 第一次添加,把 k-v 封装到 Entry 对象,放入root
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;
}
2.2 以后添加
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do { //遍历所有的key , 给当前key找到适当的位置
parent = t;
cmp = cpr.compare(key, t.key); //动态绑定到我们的匿名内部类的compare
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else //如果遍历过程中,发现准备添加 key 和当前已有的 key 相等,就不添加
return t.setValue(value);
} while (t != null);
}
*/