1.排序的引入
由於TreeSet可以實現對元素按照某種規則進行排序,例如下面的例子
1 public class TreeSetDemo { 2 public static void main(String[] args) { 3 // 創建集合對象 4 // 自然順序進行排序 5 TreeSet<Integer> ts = new TreeSet<Integer>(); 6 7 // 創建元素並添加 8 // 20,18,23,22,17,24,19,18,24 9 ts.add(20); 10 ts.add(18); 11 ts.add(23); 12 ts.add(22); 13 ts.add(17); 14 ts.add(24); 15 ts.add(19); 16 ts.add(18); 17 ts.add(24); 18 19 // 遍歷 20 for (Integer i : ts) { 21 System.out.println(i); 22 } 23 } 24 }
運行結果為:
但是對自定義對象呢?
1 public class TreeSetDemo02 { 2 public static void main(String[] args) { 3 TreeSet<Student> ts=new TreeSet<Student>(); 4 //創建元素對象 5 Student s1=new Student("zhangsan",20); 6 Student s2=new Student("lis",22); 7 Student s3=new Student("wangwu",24); 8 Student s4=new Student("chenliu",26); 9 Student s5=new Student("zhangsan",22); 10 Student s6=new Student("qianqi",24); 11 12 //將元素對象添加到集合對象中 13 ts.add(s1); 14 ts.add(s2); 15 ts.add(s3); 16 ts.add(s4); 17 ts.add(s5); 18 ts.add(s6); 19 20 //遍歷 21 for(Student s:ts){ 22 System.out.println(s.getName()+"-----------"+s.getAge()); 23 } 24 } 25 }
Student類:
1 public class Student { 2 private String name; 3 private int age; 4 5 public Student() { 6 super(); 7 // TODO Auto-generated constructor stub 8 } 9 10 public Student(String name, int age) { 11 super(); 12 this.name = name; 13 this.age = age; 14 } 15 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public int getAge() { 25 return age; 26 } 27 28 public void setAge(int age) { 29 this.age = age; 30 } 31 }
運行結果:
原因分析:
由於不知道該安照那一中排序方式排序,所以會報錯。
解決方法:
1.自然排序
2.比較器排序
2.自然排序
自然排序要進行一下操作:
1.Student類中實現 Comparable<T>接口
2.重寫Comparable接口中的Compareto方法
int |
compareTo(T o) 比較此對象與指定對象的順序。 |
故Student類為:特別注意在重寫Compareto方法時,注意排序
1 package xfcy_04; 2 /** 3 * Student類 4 * @author 曉風殘月 5 * 6 */ 7 public class Student implements Comparable<Student> { 8 private String name; 9 private int age; 10 11 public Student() { 12 super(); 13 // TODO Auto-generated constructor stub 14 } 15 16 public Student(String name, int age) { 17 super(); 18 this.name = name; 19 this.age = age; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 public int getAge() { 31 return age; 32 } 33 34 public void setAge(int age) { 35 this.age = age; 36 } 37 38 @Override 39 public int compareTo(Student s) { 40 //return -1; //-1表示放在紅黑樹的左邊,即逆序輸出 41 //return 1; //1表示放在紅黑樹的右邊,即順序輸出 42 //return o; //表示元素相同,僅存放第一個元素 43 //主要條件 姓名的長度,如果姓名長度小的就放在左子樹,否則放在右子樹 44 int num=this.name.length()-s.name.length(); 45 //姓名的長度相同,不代表內容相同,如果按字典順序此 String 對象位於參數字符串之前,則比較結果為一個負整數。 46 //如果按字典順序此 String 對象位於參數字符串之后,則比較結果為一個正整數。 47 //如果這兩個字符串相等,則結果為 0 48 int num1=num==0?this.name.compareTo(s.name):num; 49 //姓名的長度和內容相同,不代表年齡相同,所以還要判斷年齡 50 int num2=num1==0?this.age-s.age:num1; 51 return num2; 52 } 53 54 }
而主類中為:
1 package xfcy_04; 2 3 import java.util.TreeSet; 4 5 /* 6 * TreeSet存儲自定義對象並保證排序和唯一。 7 * 8 * 需求:請按照姓名的長度排序 9 */ 10 public class TreeSetDemo02 { 11 public static void main(String[] args) { 12 //創建集合對象 13 TreeSet<Student> ts=new TreeSet<Student>(); 14 15 16 //創建元素對象 17 Student s1=new Student("zhangsan",20); 18 Student s2=new Student("lis",22); 19 Student s3=new Student("wangwu",24); 20 Student s4=new Student("chenliu",26); 21 Student s5=new Student("zhangsan",22); 22 Student s6=new Student("qianqi",24); 23 24 //將元素對象添加到集合對象中 25 ts.add(s1); 26 ts.add(s2); 27 ts.add(s3); 28 ts.add(s4); 29 ts.add(s5); 30 ts.add(s6); 31 32 //遍歷 33 for(Student s:ts){ 34 System.out.println(s.getName()+"-----------"+s.getAge()); 35 } 36 } 37 }
運行結果:
3、比較器排序
比較器排序步驟:
1.單獨創建一個比較類,這里以MyComparator為例,並且要讓其繼承Comparator<T>接口
2.重寫Comparator接口中的Compare方法
3.在主類中使用下面的 構造方法
TreeSet(Comparator<? superE> comparator) 構造一個新的空 TreeSet,它根據指定比較器進行排序。 |
主類:
1 package xfcy_04; 2 3 import java.util.TreeSet; 4 5 /* 6 * TreeSet存儲自定義對象並保證排序和唯一。 7 * 8 * 需求:請按照姓名的長度排序 9 */ 10 public class TreeSetDemo02 { 11 public static void main(String[] args) { 12 //創建集合對象 13 //TreeSet(Comparator<? super E> comparator) 構造一個新的空 TreeSet,它根據指定比較器進行排序。 14 TreeSet<Student> ts=new TreeSet<Student>(new MyComparator()); 15 16 //創建元素對象 17 Student s1=new Student("zhangsan",20); 18 Student s2=new Student("lis",22); 19 Student s3=new Student("wangwu",24); 20 Student s4=new Student("chenliu",26); 21 Student s5=new Student("zhangsan",22); 22 Student s6=new Student("qianqi",24); 23 24 //將元素對象添加到集合對象中 25 ts.add(s1); 26 ts.add(s2); 27 ts.add(s3); 28 ts.add(s4); 29 ts.add(s5); 30 ts.add(s6); 31 32 //遍歷 33 for(Student s:ts){ 34 System.out.println(s.getName()+"-----------"+s.getAge()); 35 } 36 } 37 }
MyComparator類:
1 package xfcy_04; 2 3 import java.util.Comparator; 4 5 public class MyComparator implements Comparator<Student>{ 6 7 @Override 8 public int compare(Student s1,Student s2) { 9 // 姓名長度 10 int num = s1.getName().length() - s2.getName().length(); 11 // 姓名內容 12 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num; 13 // 年齡 14 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; 15 return num3; 16 } 17 18 19 20 21 }
學生類(不需要繼承Comparetable接口)
1 package xfcy_04; 2 /** 3 * Student類 4 * @author 曉風殘月 5 * 6 */ 7 public class Student{ 8 private String name; 9 private int age; 10 11 public Student() { 12 super(); 13 // TODO Auto-generated constructor stub 14 } 15 16 public Student(String name, int age) { 17 super(); 18 this.name = name; 19 this.age = age; 20 } 21 22 public String getName() { 23 return name; 24 } 25 26 public void setName(String name) { 27 this.name = name; 28 } 29 30 public int getAge() { 31 return age; 32 } 33 34 public void setAge(int age) { 35 this.age = age; 36 } 37 38 }
運行結果:
4.比較器修改(代碼精簡)
由於單獨創建一個類不是特別好,因而可以將MyComparetor的內容直接寫到主類中
1 public class TreeSetDemo { 2 public static void main(String[] args) { 3 // 如果一個方法的參數是接口,那么真正要的是接口的實現類的對象 4 // 而匿名內部類就可以實現這個東西 5 TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { 6 @Override 7 public int compare(Student s1, Student s2) { 8 // 姓名長度 9 int num = s1.getName().length() - s2.getName().length(); 10 // 姓名內容 11 int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) 12 : num; 13 // 年齡 14 int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2; 15 return num3; 16 } 17 }); 18 19 // 創建元素 20 Student s1 = new Student("linqingxia", 27); 21 Student s2 = new Student("zhangguorong", 29); 22 Student s3 = new Student("wanglihong", 23); 23 Student s4 = new Student("linqingxia", 27); 24 Student s5 = new Student("liushishi", 22); 25 Student s6 = new Student("wuqilong", 40); 26 Student s7 = new Student("fengqingy", 22); 27 Student s8 = new Student("linqingxia", 29); 28 29 // 添加元素 30 ts.add(s1); 31 ts.add(s2); 32 ts.add(s3); 33 ts.add(s4); 34 ts.add(s5); 35 ts.add(s6); 36 ts.add(s7); 37 ts.add(s8); 38 39 // 遍歷 40 for (Student s : ts) { 41 System.out.println(s.getName() + "---" + s.getAge()); 42 } 43 } 44 }
運行結果也如同上面一樣
5.總結
A:自然排序:要在自定義類中實現Comparerable<T>接口 ,並且重寫compareTo方法
B:比較器排序:在自定義類中實現Comparetor<t>接口,重寫compare方法