用TreeSet存储Integer类型数据并遍历
20,18,23,22,17,24,19,18,24
1 package cn.itcast_05;
2
3 import java.util.TreeSet;
4
5 /*
6 * TreeSet:能够对元素按照某种规则进行排序。
7 * 排序有两种方式(具体那种方式取决于使用TreeSet的构造方法)
8 * A:自然排序
9 * B:比较器排序
10 *
11 * TreeSet集合的特点:排序和唯一
12 *
13 * 通过观察TreeSet的add()方法,我们知道最终要看TreeMap的put()方法。
14 */
15 public class TreeSetDemo {
16 public static void main(String[] args) {
17 // 创建集合对象
18 // TreeSet的无参构造:自然顺序进行排序
19 TreeSet<Integer> ts = new TreeSet<Integer>();
20
21 // 创建元素并添加进集合
22 // 20,18,23,22,17,24,19,18,24
23 // Integer i1 = new Integer(200);
24 // ts.add(i1);
25 ts.add(20); // 自动装箱
26 ts.add(18);
27 ts.add(23);
28 ts.add(22);
29 ts.add(17);
30 ts.add(24);
31 ts.add(19);
32 ts.add(18);
33 ts.add(24);
34
35 // 遍历集合
36 for (Integer i : ts) {
37 System.out.println(i);
38 }
39 }
40 }
TreeSet集合的add()方法的源码
---------------------------------------
interface Collection {
...
}
interface Set extends Collection {
...
}
---------------------------------------
class TreeSet implements Set {
...
private static final Object PRESENT = new Object();
private transient NavigableMap<E,Object> m;
public TreeSet() {
this(new TreeMap<E,Object>());
}
public boolean add(E e) {
return m.put(e, PRESENT)==null;
}
...
}
---------------------------------------
class TreeMap implements NavigableMap {
...
public V put(K key, V value) {
Entry<K,V> t = root; // 先造根,TreeSet集合底层数据结构是红黑树(是一个自平衡的二叉树)
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator; // 因为用的是TreeSet的无参构造方法,是自然排序,没有用到comparator比较器
if (cpr != null) { // 所以此时的comparator = null,则程序执行else里面的代码
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);
} else {
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key; // 此接口Comparable强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。。
do { // 举例中我们使用的是包装类Intrger,而Integer类实现了Comparable接口。此例子是向上转型。
parent = t;
cmp = k.compareTo(t.key); // 类的 compareTo 方法被称为它的自然比较方法。
if (cmp < 0) // int compareTo(T o) 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
...
}
---------------------------------------
由上可知:真正的比较是依赖于元素的compareTo()方法,而这个方法compareTo()是定义在 Comparable接口里面的(抽象方法)。
所以,你要想重写该方法,就必须是先实现 Comparable接口。这个接口表示的就是自然排序。
---------------------------------------