TreeSet底层是TreeMap,二者区别在于:
java
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
TreeSet在使用方法时,e作为元素添加,而PRESENT作为一个用于占位的空对象,表示没有意义
TreeMap使用方法时,由于是作为键值对添加进去的,此时e 就等于key,而PRESENT 就等于value
TreeSet演示:

java
package com.CollectionStu_.Set_;
import java.util.Comparator;
import java.util.TreeSet;
@SuppressWarnings({"all"})
public class TreeSet_ {
public static void main(String[] args) {
// TreeSet treeSet = new TreeSet();
//1.当我们使用无参构造器创建TreeSet时,仍然是无序的
//2.可以使用TreeSet提供的一个构造器,可以传入一个比较器(匿名内部类)
// 并指定排序规则
//例:希望添加的元素能够按照字符串大小进行排序(这里是从小到大)
TreeSet treeSet = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
//下面调用String的 compareTo方法进行字符串大小比较
return ((String)o2).compareTo((String) o1);//从大到小把o2 和o1 对调即可
}
});
//添加数据
treeSet.add("jack");
treeSet.add("tom");
treeSet.add("nihao");
treeSet.add("mary");
System.out.println(treeSet);
//排序前(直接输出):[jack, mary, nihao, tom]
//排序后(从小到大):[tom, nihao, mary, jack]
//源码分析:
/*
构造器:
public TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<>(comparator));
}
构造器会把传入的匿名对象new Comparator() 赋给TreeSet底层的TreeMap的属性this.comparator
在调用add("tom") 时,在底层会执行到
Comparator<? super K> cpr = comparator; //cpr就是匿名内部类(对象)
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key); //动态绑定到匿名内部类的compare()
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else //如果相等,即返回0,这个数据(Key)就没有加入
return t.setValue(value);
} while (t != null);
}
*/
}
}
TreeMap演示:

java
package com.MapStu_.Map_;
import java.util.Comparator;
import java.util.TreeMap;
@SuppressWarnings({"all"})
public class TreeMap_ {
public static void main(String[] args) {
TreeMap treeMap = new TreeMap();
treeMap.put("jack","杰克");
treeMap.put("tom","汤姆");
treeMap.put("nihao","泥嚎");
treeMap.put("smith","史密斯");
//使用默认构造器创建TreeMap(无序的,也没有排序)
System.out.println(treeMap);//{jack=杰克, nihao=泥嚎, smith=史密斯, tom=汤姆}
//使用带comparator的构造器控制排序
// public TreeMap(Comparator<? super K> comparator) {
// this.comparator = comparator;
// }
//例:要求按照传入的key(String) 大小进行排序
TreeMap treeMap1 = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).compareTo((String)o2);
}
});
treeMap1.put("jack","杰克");
treeMap1.put("tom","汤姆");
treeMap1.put("nihao","泥嚎");
treeMap1.put("smith","史密斯");
System.out.println(treeMap1);
//要求按照字符串长度大小排序
TreeMap treeMap2 = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
return ((String)o1).length() - ((String)o2).length();
}
});
/*
源码解读:
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);
}
*/
}
}