本次博客带领大家了解集合中的TreeSet和TreeMap的源码分析。
TreeSet的源码分析
//TreeSet treeSet = new TreeSet();
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//下面调用String的 compareTo方法进行字符串大小比较
//return ((String) o1).compareTo((String) o2);
//按照长度大小排序
return ((String) o1).length()-((String) o2).length();
}
});
//添加数据
treeSet.add("jack");
treeSet.add("tom");
treeSet.add("sp");
treeSet.add("a");
System.out.println("treeSet="+treeSet);
1.当我们使用无参构造器,创建TreeSet时,仍然是无序的
2.希望添加的元素,按照字符串大小来排序
3.使用TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类),并指定排序规则
4.构造器把传入的比较器对象,赋给了 TreeSet的底层的TreeMap的属性
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
5.在 调用 treeSet.add("tom"),在底层会执行到
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);
}
TreeMap的源码分析
//TreeMap treeMap = new TreeMap();
TreeMap treeMap = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//下面调用String的 compareTo方法进行字符串大小比较
//return ((String) o1).compareTo((String) o2);
//按照长度大小排序
return ((String) o1).length()-((String) o2).length();
}
});
treeMap.put("jack","杰克");
treeMap.put("tom","汤姆");
treeMap.put("kristina","克瑞斯提努");
treeMap.put("smith","史密斯");
treeMap.put("abc","222");
System.out.println("treemap="+treeMap);
1.构造器,把传入的实现了 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相等,就替换value
return t.setValue(value);
} while (t != null);
}