TreeSet拥有和Set的基础属性:不能重复。
同时它还拥有一个隐藏排序功能。
public class RandomTest { public static void main(String[] args) { Random random = new Random(); Setset = new TreeSet (); 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 SortedMapm; // The backing Map private static final Object PRESENT = new Object();
看m的初始化
public TreeSet() { this(new TreeMap()); }
基本明白了,TreeSet是实际上使用了一个含排序功能的TreeMap存放的数据,key是Set集合中的元素,value是一个虚拟Object。
看TreeMap的put方法
public V put(K key, V value) { Entryt = root; if (t == null) { incrementSize(); root = new Entry (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 (key, value, t); fixAfterInsertion(t.left); return null; } } else { // cmp > 0 if (t.right != null) { t = t.right; } else { incrementSize(); t.right = new Entry (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(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(); // 使用指定的构造方法 Setset = new TreeSet (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 { 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