前言:TreeSet集合是Set集合的一個子實現類,它是基於TreeMap中的NavigableSet接口實現的,TreeSet集合是默認經過天然排序將集合中的元素進行排序java
TreeSet有兩種排序方式:面試
1)天然排序api
2)比較器排序(定製排序)dom
當定製排序和天然排序同時存在時,最終的排序結果是按照 定製排序 來的。ide
面試題:Comparable 和Comparator的區別:工具
① Comparable 天然排序 ,實體類實現Comparable接口,能夠去重寫compareTo()方法,解決實際排序問題。 把元素放到TreeSet裏面去,就會自動的調用CompareTo方法; 可是這個Comparable並非專爲TreeSet設計的;只是說TreeSet順便利用而已; 就像haashCode和equals 也同樣,不是說專門爲HashSet設計同樣;只是你順便利用而已;this
② Compartor第三方的比較器接口,也不是專門爲TreeSet設計。 用法:設計一個比較器. 建立一個類,實現這個接口,覆寫compare()方法,解決不一樣問題的需求。spa
1. 天然排序:設計
在TreeSet中默認要求裏面的元素進行天然排序,強制要求裏面的全部元素必須按照Comparable中的compareTo方法進行比較。code
若是容器裏面的對象(好比:new Student(參數)對象)不具有compareTo方法此時就會拋出異常報錯(ClassCastException),因此必需要讓容器中的元素實現Comparable接口,這樣它才具有compareTo方法。
1.TreeSet實例在調用add方法時會調用容器對象的compareTo方法對元素進行比較
2.TreeSet實例中對象必須是實現了Comparable接口
例如:比較Student學生類,應該從哪些方法進行比較?
通常從字段的方面進行比較;好比按照年齡比較;當年齡相等返回0,大於返回1,小於返回-1
姓名是字符串,怎樣比較大小,查看api的時候,String已經實現了Comparable接口,String 類裏面已經確定覆寫Comparable方法,那是按照String的規則進行比較。
能夠直接無論具體內 部是怎樣比較,直接調用String類裏面比較方法就能夠.
package TreeSet; public class Student implements Comparable { private int age; private String name; public Student(){} public Student(int age,String name){ this.age = age; this.name = name; } @Override public int compareTo(Object obj) { //好比按照年齡比較;當年齡相等返回0,大於返回1,小於返回-1 Student stu = (Student)obj; if(this.age > stu.age){ return 1; }else if(this.age<stu.age){ return -1; }else{ return this.name.compareTo(stu.name); } } @Override public String toString() { return "<" + age + ", " + name + ">"; } }
public class TestStudent { public static void main(String[] args) { TreeSet set = new TreeSet(); set.add(new Student(20, "zs")); set.add(new Student(21, "zs")); set.add(new Student(22, "ww")); set.add(new Student(23, "zl")); System.out.println(set); } } //結果:[<20, zs>, <21, zs>, <22, ww>, <23, zl>]
2)比較器排序 建立TreeSet時,向其中傳入已經重寫Comparator中方法的對象
下面經過一個案例瞭解定製排序:
題目: 某班30個學生的學號爲20070301-20070330,所有選修了Java程序設計課程,給出全部同窗的成績(可用隨機數產生,範圍60-100),
請編寫程序將本班各位同窗的成績按照從低到高排序打印輸出。
要求:1.分別用List、Set來實現,打印的信息包括學號、姓名和成績。
2.用迭代器遍歷
public class Student { private String name; private int id; private int score; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public Student(){} public Student(String name, int id, int score) { super(); this.name = name; this.id = id; this.score = score; } @Override public String toString() { return "學生 [姓名=" + name + ", 學號=" + id + ", 成績=" + score + "]"; }
import java.util.Comparator; public class myComparator implements Comparator{ @Override public int compare(Object o1, Object o2) { Student s1 = (Student)o1; Student s2 = (Student)o2; if(s1.getScore()>s2.getScore()){ return 1; }else if(s1.getScore()<s2.getScore()){ return -1; }else{ return s1.getName().compareTo(s2.getName()); } } }
package 學生成績排序題目; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.TreeSet; public class Test { public static void main(String[] args) { //使用list集合+定製排序+迭代器遍歷(注意list.sort(), list不支持天然排序) List list = new ArrayList(); for(int i =20070301;i<=20070330;i++){ Student s = new Student("代號$"+(i-20070300),i,(int)(Math.random()*41+60)); list.add(s); } /* //這裏涉及list集合排序的兩種方法 list.sort(new myComparator()); //這裏介紹Collections工具類的sort()方法: //參數不一樣: 1. void sort(List list),按天然排序的升序排序 // 2. void sort(List list, Comparator c);定製排序,由Comparator控制排序邏輯 // 1. Collections.sort(list); //這裏因爲Student類中沒有實現天然排序,因此直接調用會報類型轉換異常 ClassCastException // 2. Collections.sort(list,new myComparator()); //能夠正常排序 Iterator it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } */ //使用TreeSet集合+定製排序+迭代器遍歷,並統計個數(也可使用treeSet的天然排序) TreeSet set = new TreeSet(new myComparator()); for(int i =20070301;i<=20070330;i++){ Student s = new Student("代號$"+(i-20070300),i,(int)(Math.random()*41+60)); set.add(s); } Iterator it = set.iterator(); int count = 0; while(it.hasNext()){ count++; System.out.println(count); System.out.println(it.next()); } } }
結果: 1 學生 [姓名=代號$10, 學號=20070310, 成績=60] 2 學生 [姓名=代號$12, 學號=20070312, 成績=60] 3 學生 [姓名=代號$26, 學號=20070326, 成績=60] 4 學生 [姓名=代號$1, 學號=20070301, 成績=61] 5 學生 [姓名=代號$28, 學號=20070328, 成績=65] 6 學生 [姓名=代號$21, 學號=20070321, 成績=69] 7 學生 [姓名=代號$11, 學號=20070311, 成績=71] 8 學生 [姓名=代號$24, 學號=20070324, 成績=71] 9 學生 [姓名=代號$16, 學號=20070316, 成績=72] 10 學生 [姓名=代號$5, 學號=20070305, 成績=72] 11 學生 [姓名=代號$9, 學號=20070309, 成績=73] 12 學生 [姓名=代號$2, 學號=20070302, 成績=74] 13 學生 [姓名=代號$3, 學號=20070303, 成績=74] 14 學生 [姓名=代號$20, 學號=20070320, 成績=76] 15 學生 [姓名=代號$6, 學號=20070306, 成績=78] 16 學生 [姓名=代號$14, 學號=20070314, 成績=79] 17 學生 [姓名=代號$29, 學號=20070329, 成績=79] 18 學生 [姓名=代號$7, 學號=20070307, 成績=79] 19 學生 [姓名=代號$18, 學號=20070318, 成績=80] 20 學生 [姓名=代號$17, 學號=20070317, 成績=83] 21 學生 [姓名=代號$25, 學號=20070325, 成績=87] 22 學生 [姓名=代號$13, 學號=20070313, 成績=88] 23 學生 [姓名=代號$15, 學號=20070315, 成績=89] 24 學生 [姓名=代號$30, 學號=20070330, 成績=89] 25 學生 [姓名=代號$8, 學號=20070308, 成績=90] 26 學生 [姓名=代號$23, 學號=20070323, 成績=92] 27 學生 [姓名=代號$19, 學號=20070319, 成績=93] 28 學生 [姓名=代號$27, 學號=20070327, 成績=93] 29 學生 [姓名=代號$4, 學號=20070304, 成績=93] 30 學生 [姓名=代號$22, 學號=20070322, 成績=98]