標籤:java treeset set
TreeSet :可以對Set集合中的元素進行排序
排序是按照ascii來排序的。
import java.util.Iterator;import java.util.TreeSet;public class TreeSetDemo {public static void main(String[] args) {// TODO Auto-generated method stubmethod1();}public static void method1() {TreeSet ts = new TreeSet();ts.add("cba");ts.add("aaa");ts.add("bca");ts.add("abcd");Iterator it = ts.iterator();while (it.hasNext()) {System.out.println(it.next());}/** * 列印結果是: aaa abcd bca cba treeset中元素是有順序的 是按照ascii碼來排序的 */}}
自訂類Student,中有屬性name和age,按照age 從小到大排序。
import java.util.Iterator;import java.util.TreeSet;class Student {private String name;private int age;public Student(String name, int age) {super();this.name = name;this.age = age;}// set and get methodspublic String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}public class TreeSetDemo {public static void main(String[] args) {// TODO Auto-generated method stubTreeSet ts = new TreeSet();ts.add(new Student("01", 10));ts.add(new Student("02", 15));ts.add(new Student("03", 9));ts.add(new Student("04", 18));Iterator it = ts.iterator();while (it.hasNext()){Student student = (Student) it.next();System.out.println(student.getName() +"::::"+student.getAge());}}}
運行發現出現錯誤:
Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to java.lang.Comparableat java.util.TreeMap.compare(TreeMap.java:1290)at java.util.TreeMap.put(TreeMap.java:538)at java.util.TreeSet.add(TreeSet.java:255)at TreeSetDemo.main(TreeSetDemo.java:39)
因為TreeSet是一個有序的集合,它要知道它裡邊的元素是如何進行排列的,所以需要Student類實現Comparable介面.
Comparable介面強行實現它的每個類的對象進行整體排序,這種排序被稱為自然排序。此介面中只有一個方法compareToxuyao 複寫。
import java.util.Iterator;import java.util.TreeSet;class Student implements Comparable{private String name;private int age;public Student(String name, int age) {super();this.name = name;this.age = age;}// set and get methodspublic String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int compareTo(Object o) {if (!(o instanceof Student))throw new RuntimeException("不是學生對象");Student student = (Student) o;if (this.age > student.age)return 1;if (this.age == student.age)return 0;return -1;}}public class TreeSetDemo {public static void main(String[] args) {// TODO Auto-generated method stubTreeSet ts = new TreeSet();ts.add(new Student("01", 10));ts.add(new Student("02", 15));ts.add(new Student("03", 9));ts.add(new Student("04", 18));Iterator it = ts.iterator();while (it.hasNext()){Student student = (Student) it.next();System.out.println(student.getName() +"::::"+student.getAge());}}}
通過複寫這個方法,可以列印出結果:
03::::901::::1002::::1504::::18
但是當添加一個與已有元素年齡相同但是姓名不同的元素卻添加不上。。
我們加上這麼一個元素
ts.add(new Student("05", 18));
但是顯示結果卻沒有它。因為在這個compareTo方法中認為年齡相同的就是同一個元素,為此,當年齡相同時我們還要再做一次判斷,判斷其姓名是否也相同。
我們將compareTo方法修改如下:
public int compareTo(Object o) {if (!(o instanceof Student))throw new RuntimeException("不是學生對象");Student student = (Student) o;if (this.age > student.age)return 1;if (this.age == student.age) {return this.name.compareTo(student.name);}return -1;}
再次運行就會發現,05元素存入到集合中了。那麼TreeSet 是如何進行比較的呢?
我們在compareTo方法中添加這麼一句:
System.out.println(this.name + "-----compaerTo-----" + student.name);
用來顯示其運行過程。
public int compareTo(Object o) {if (!(o instanceof Student))throw new RuntimeException("不是學生對象");Student student = (Student) o;System.out.println(this.name + "-----compaerTo-----" + student.name);if (this.age > student.age)return 1;if (this.age == student.age) {return this.name.compareTo(student.name);}return -1;}
運行結果:
02-----compaerTo-----0103-----compaerTo-----0104-----compaerTo-----0104-----compaerTo-----0205-----compaerTo-----0105-----compaerTo-----0205-----compaerTo-----0403::::901::::1002::::1504::::1805::::18
通過這個結果,我們可瞭解到此程式的運行過程:
首先,01先存入
02與01進行比較,存入
03與01比較,存入
04與01 02 比較 存入
05和01 02 04比較 存入
為什麼是這個樣子的呢?為什麼不是和此元素之前的所有元素進行比較呢?就是因為TreeSet的底層資料結構是二叉樹。
我們根據此程式畫了一張圖,當第一個元素存入的時候,為此元素建立一個節點10(年齡),此後的元素在存入的時候,會跟10這個節點進行比較,比他小的在它左邊建立一個節點,比他大的在它右邊建立節點,以此類推,如04存入的時候,先跟10比較,比10大,應該存放到右邊,但是右邊有元素15,再跟15比較,比15大,在15的右邊建立節點,存入。
Java---28---Set集合之TreeSet