总结-开发中如何选择集合实现类(记住!)
以下为 TreeSet 和 TreeMap 源码简单分析
TreeSet_.java 底层源码分析
package com.xjz.set_;
import java.util.Comparator;
import java.util.TreeSet;
@SuppressWarnings({"all"})
public class TreeSet_ {
public static void main(String[] args) {
//1. 当我们使用无参构造器,创建TreeSet时,仍然是无序的
//2. 如果希望添加是元素,按照字符串大小来排序
//3. 使用 TreeSet 提供的一个构造器,可以传入一个比较器(匿名内部类)
// 并制定排序规则
//4. 简单看看源码
/*
1. 构造器把传入的比较器对象,赋给了 TreeSet的底层的 TreeMap的属性 this.comparator
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
2. 在 调用 treeSet.add("tom"); 时,在底层会执行到
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 //如果相同,即返回0,这个 Key 就没有加入
return t.setValue(value);
} while (t != null);
}
*/
//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);
//TreeSet=[a, abc, jack, sp, tom] //asc从小到大
return ((String)o1).length() - ((String)o2).length();
//T reeSet=[a, sp, tom, jack] //字符串长度从小到大
}
});
//添加数据
treeSet.add("jack");
treeSet.add("tom");
treeSet.add("sp");
treeSet.add("a");
//treeSet.add("tom"); //如果相等,则加入不了--> compareTo
treeSet.add("abc"); //长度相等,则加入不了 --> length()
System.out.println("TreeSet=" + treeSet);
}
}
TreeMap_.java 底层源码分析
package com.xjz.map_;
import java.util.Comparator;
import java.util.TreeMap;
@SuppressWarnings({"all"})
public class TreeMap_ {
public static void main(String[] args) {
//使用默认的构造器,创建TreeMap,是无序的(也没有排序)
/*
要求:按照传入的 k(String) 的大小排序
*/
//TreeMap treeMap = new TreeMap();
TreeMap treeMap = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//按照传入的 k(String) 的大小进行排序
/*
return ((String)o1).compareTo((String)o2);
输出:treeMap={jack=杰克, kristina=克瑞斯提诺,smith=史密斯,tom=汤姆 }
*/
//按照 K(String) 的长度大小排序
return ((String)o1).length() - ((String)o2).length();
//treeMap={tom=汤姆, jack=杰克, smith=史密斯, kristina=克瑞斯提诺}
}
});
treeMap.put("jack", "杰克");
treeMap.put("tom", "汤姆");
treeMap.put("kristina", "克瑞斯提诺");
treeMap.put("smith", "史密斯");
treeMap.put("qdy","秋刀鱼");//添加不了,Key 长度相同
System.out.println("treeMap=" + 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);
}
*/
}
}