TreeSet拥有和Set的基础属性:不能重复。
同时它还拥有一个隐藏排序功能。
public class RandomTest {
public static void main(String[] args) {
Random random = new Random();
Set<Integer> set = new TreeSet<Integer>();
while (set.size() != 6) {
// 获取随机数
int randomValue = random.nextInt(33) + 1;
System.out.print(randomValue + " ");
// 写入TreeSet集合
set.add(randomValue);
}
System.out.println("\n------------");
Iterator it = set.iterator();
// 输出TreeSet内容
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
}
输出
15 4 23 4 9 19 8
------------
4 8 9 15 19 23
在随机数放入TreeSet之后,再次输出时进行了排序。
看TreeSet的源码的add方法
public boolean add(E o) {
return m.put(o, PRESENT)==null;
}
再看m和PRESENT是什么
private transient SortedMap<E,Object> m; // The backing Map
private static final Object PRESENT = new Object();
看m的初始化
public TreeSet() {
this(new TreeMap<E,Object>());
}
基本明白了,TreeSet是实际上使用了一个含排序功能的TreeMap存放的数据,key是Set集合中的元素,value是一个虚拟Object。
看TreeMap的put方法
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
incrementSize();
root = new Entry<K,V>(key, value, null);
return null;
}
while (true) {
int cmp = compare(key, t.key);
if (cmp == 0) {
return t.setValue(value);
} else if (cmp < 0) {
if (t.left != null) {
t = t.left;
} else {
incrementSize();
t.left = new Entry<K,V>(key, value, t);
fixAfterInsertion(t.left);
return null;
}
} else { // cmp > 0
if (t.right != null) {
t = t.right;
} else {
incrementSize();
t.right = new Entry<K,V>(key, value, t);
fixAfterInsertion(t.right);
return null;
}
}
}
}
它进行了排序,但排序的关键是compare方法,该方法制定和TreeMap的key值顺序,也就是TreeSet的元素顺序
private Comparator<? super K> comparator = null;
private int compare(K k1, K k2) {
return (comparator==null ? ((Comparable</*-*/K>)k1).compareTo(k2)
: comparator.compare((K)k1, (K)k2));
}
如果我们想要修改TreeSet的排序,那么需要重写TreeMap的compare方法,即自定义comparator,其实TreeMap和TreeSet已经提供了入口
public TreeSet(Comparator<? super E> c) {
this(new TreeMap<E,Object>(c));
}
public TreeMap(Comparator<? super K> c) {
this.comparator = c;
}
修改一下之前的代码,我们自定义Comparator,让TreeSet的元素倒序输出
public class RandomTest {
public static void main(String[] args) {
Random random = new Random();
// 自定义的Comparater
MyComparater comparater = new MyComparater();
// 使用指定的构造方法
Set<Integer> set = new TreeSet<Integer>(comparater);
while (set.size() != 6) {
// 获取随机数
int randomValue = random.nextInt(33) + 1;
System.out.print(randomValue + " ");
// 写入TreeSet集合
set.add(randomValue);
}
System.out.println("\n------------");
Iterator it = set.iterator();
// 输出TreeSet内容
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
}
}
class MyComparater implements Comparator<Integer>{
public int compare(Integer o1, Integer o2) {
int val1 = o1.intValue();
int val2 = o2.intValue();
return (val1 > val2 ? -1 : (val1 == val2 ? 0 : 1));
}
}
输出:
3 16 16 25 5 3 21 11
------------
25 21 16 11 5 3