TreeSet:
1.特點
TreeSet是用來排序的, 可以指定一個順序, 對象存入之后會按照指定的順序排列
2.使用方式
a.自然順序(Comparable)
TreeSet類的add()方法中會把存入的對象提升為Comparable類型
調用對象的compareTo()方法和集合中的對象比較(當前存入的是誰,誰就會調用compareTo方法)
根據compareTo()方法返回的結果進行存儲
b.比較器順序(Comparator)
創建TreeSet的時候可以制定 一個Comparator
如果傳入了Comparator的子類對象, 那么TreeSet就會按照比較器中的順序排序
add()方法內部會自動調用Comparator接口中compare()方法排序
調用的對象(就是當前存入的對象)是compare方法的第一個參數,集合中的對象(已經添加進去的對象)是compare方法的第二個參數
c.兩種方式的區別
TreeSet構造函數什么都不傳, 默認按照類中Comparable的順序(沒有就報錯ClassCastException)
TreeSet如果傳入Comparator, 就優先按照Comparator
1. TreeSet存儲Integer類型的元素
package online.msym.set; import java.util.Comparator; import java.util.TreeSet; import online.msym.bean.Person; public class Demo3_TreeSet { /** * @param args * TreeSet集合是用來對象元素進行排序的,同樣他也可以保證元素的唯一 */ public static void main(String[] args) { demo1(); } public static void demo1() { TreeSet<Integer> ts = new TreeSet<>(); ts.add(3); ts.add(1); ts.add(1); ts.add(2); ts.add(2); ts.add(3); ts.add(3); System.out.println("TreeSet存儲Integer類型的元素: " + ts); } }
2. TreeSet存儲自定義對象
package online.msym.set; import java.util.Comparator; import java.util.TreeSet; import online.msym.bean.Person; public class Demo3_TreeSet { /** * @param args * TreeSet集合是用來對象元素進行排序的,同樣他也可以保證元素的唯一 * 當compareTo方法返回0的時候集合中只有一個元素 * 當compareTo方法返回正數的時候集合會怎么存就怎么取 * 當compareTo方法返回負數的時候集合會倒序存儲 */ public static void main(String[] args) { demo2(); } public static void demo2() { //因為TreeSet要對元素進行排序,那你排序的依據是什么,姓名還是年齡還是其它的,得告訴它,怎么告訴? //需要讓Person類實現Comparable接口重寫compareTo方法 TreeSet<Person> ts = new TreeSet<>(); ts.add(new Person("張三", 23)); ts.add(new Person("李四", 13)); ts.add(new Person("周七", 13)); ts.add(new Person("王五", 43)); ts.add(new Person("趙六", 33)); System.out.println(ts); } }
注意上面的輸出,跟添加的順序相反,那是因為compareTo方法的返回值
Person實體類:
package online.msym.bean; //為了簡化代碼,這里沒有hashCode和equals方法,用的話可以直接將上面的Person類中的hashCode和equals復制過來 public class Person implements Comparable<Person> { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public 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; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]\n"; } public int compareTo(Person o) { //return 0; //return 1; return -1 } }
TreeSet保證元素唯一和自然排序的原理和圖解
TreeSet保證元素唯一和自然排序的原理和圖解,小的放左側,大的放右側
按照Person類的年齡排序的話,Person類改寫為:
//注意使用此類時要生成空參有參構造,set和get方法,hashCode和equals方法 package online.msym.bean; public class Person implements Comparable<Person> { private String name; private int age; @Override //按照年齡排序 public int compareTo(Person o) {
int num = this.age - o.age; //按照年齡比較return num;
//return num == 0 ? this.name.compareTo(o.name) : num;//姓名是比較的次要條件 } }
TreeSet保證元素唯一和比較器排序的原理:
定義比較器是實現Comparator接口,重寫compare方法和equals方法,但是由於所有的類默認繼承Object,而Object中有equals方法,
所以自定義比較器類時,不用重寫equals方法,只需要重寫compare方法
字符串長度比較器圖解:
下面采用了兩種方式:匿名的內部類的比較器對象,自定義的比較器對象,
package online.msym.test; import java.util.Comparator; import java.util.TreeSet; import online.msym.bean.Person; public class Demo3_TreeSet { public static void main(String[] args) { //demo1(); demo2(); } private static void demo2() { // 需求:將字符串按照長度排序, (利用匿名內部類對象, 長度從大到小, 長度相同按照字母倒序) TreeSet<String> ts = new TreeSet<>(new Comparator<String>() { @Override public int compare(String s1, String s2) { int num = s2.length() - s1.length(); // 長度為主要條件 return num == 0 ? s2.compareTo(s1) : num; // 內容為次要條件 } }); ts.add("aaaaaaaa"); ts.add("z"); ts.add("wc"); ts.add("nba"); ts.add("cba"); System.out.println(ts); } private static void demo1() { // 需求:將字符串按照長度排序,(傳遞一個自定義的比較器對象) TreeSet<String> ts = new TreeSet<>(new CompareByLen()); // Comparator c = new CompareByLen(); ts.add("aaaaaaaa"); ts.add("z"); ts.add("wc"); ts.add("nba"); ts.add("cba"); System.out.println(ts); } } class CompareByLen /* extends Object */implements Comparator<String> {//實現一個比較器類 @Override public int compare(String s1, String s2) { // 按照字符串的長度比較 int num = s1.length() - s2.length(); // 長度為主要條件 return num == 0 ? s1.compareTo(s2) : num; // 內容為次要條件 } }