TreeSet集合的自然排序與比較器排序、Comparable接口的compareTo()方法


【自然排序】

 1 package com.hxl;
 2 
 3 public class Student implements Comparable<Student> {
 4 
 5     private String name;
 6     private int age;
 7 
 8     public Student() {
 9         super();
10     }
11 
12     public Student(String name, int age) {
13         super();
14         this.name = name;
15         this.age = age;
16     }
17 
18     public String getName() {
19         return name;
20     }
21 
22     public void setName(String name) {
23         this.name = name;
24     }
25 
26     public int getAge() {
27         return age;
28     }
29 
30     public void setAge(int age) {
31         this.age = age;
32     }
33 
34     @Override
35     public int compareTo(Student s) {
36         // 先讓兩個對象的age屬性做差比較,這個是主要排序條件
37         int num = this.age - s.age;
38         // 若age屬性相同,再比較name屬性(String類本身實現了Comparable接口)
39         // 即在主要排序條件相同的情況下,次要排序條件起作用
40         int flag = num == 0 ? this.name.compareTo(s.name) : num;
41         // 返回比較結果
42         return flag;
43     }
44 }
 1 package com.hxl;
 2 
 3 import java.util.TreeSet;
 4 
 5 public class Test {
 6     public static void main(String[] args) {
 7         //這里使用的無參構造實例化TreeSet集合,則默認啟用的是自然排序
 8         TreeSet<Student> ts = new TreeSet<Student>();
 9         ts.add(new Student("cc", 11));
10         ts.add(new Student("ee", 11));
11         ts.add(new Student("cc", 22));
12         ts.add(new Student("aa", 22));
13         ts.add(new Student("bb", 11));
14 
15         for (Student s : ts) {
16             System.out.println(s.getName()+"_"+s.getAge());
17         }
18 
19         /*
20             為什么TreeSet集合中的元素既唯一又有序呢?
21             原因是它在存儲元素的時候就是有序存儲的(紅黑樹結構存儲)
22             TreeSet的add()方法底層依賴的是Comparable的compareTo方法
23             這里就是說元素類本身要有自己的compareTo方法
24             所以元素類本身必須實現Comparable接口,重寫compareTo方法
25             compareTo方法有個特點:它返回的是int型數據,結果有三類負數、0、正數
26             例如:(Java中一些常見的有比較意義的一些類都實現了Comparable接口,如Integer類)
27                 Integer a = new Integer(10);
28                 Integer b = new Integer(20);
29                 int num = a.compareTo(b);     //因為a小於b,所以num返回的是負數
30             而TreeSet的add()方法這樣理解此返回值:
31             即返回負數則比根節點小,元素在此集合中唯一,元素存放根的左孩子
32             返回正數則比根節點大,元素在此集合中唯一,元素存放根的右孩子
33             返回0則表示,元素相同,在此集合中不唯一,故而丟掉不存放
34             由此可見,我們的重寫的compareTo()方法決定了TreeSet集合中元素的去留和順序!
35         */
36     }
37 }

【比較器排序(外部類實現)】

 1 package com.hxl;
 2 
 3 public class Student{
 4 
 5     private String name;
 6     private int age;
 7 
 8     public Student() {
 9         super();
10     }
11 
12     public Student(String name, int age) {
13         super();
14         this.name = name;
15         this.age = age;
16     }
17 
18     public String getName() {
19         return name;
20     }
21 
22     public void setName(String name) {
23         this.name = name;
24     }
25 
26     public int getAge() {
27         return age;
28     }
29 
30     public void setAge(int age) {
31         this.age = age;
32     }
33 }
 1 package com.hxl;
 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         // 先讓兩個對象的age屬性做差比較,這個是主要排序條件
10         int num = s1.getAge() - s2.getAge();
11         // 若age屬性相同,再比較name屬性(String類本身實現了Comparable接口)
12         // 即在主要排序條件相同的情況下,次要排序條件起作用
13         int flag = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
14         // 返回比較結果
15         return flag;
16     }
17 }
 1 package com.hxl;
 2 
 3 import java.util.TreeSet;
 4 
 5 public class Test {
 6     public static void main(String[] args) {
 7         //這里使用TreeSet(Comparator comparator)構造實例化TreeSet集合,則啟用的是指定比較器排序
 8         TreeSet<Student> ts = new TreeSet<Student>(new MyComparator());
 9         ts.add(new Student("cc", 11));
10         ts.add(new Student("ee", 11));
11         ts.add(new Student("cc", 22));
12         ts.add(new Student("aa", 22));
13         ts.add(new Student("bb", 11));
14 
15         for (Student s : ts) {
16             System.out.println(s.getName()+"_"+s.getAge());
17         }
18     }
19 }

【比較器排序(內部類實現,如果只使用一次的話)】

 1 package com.hxl;
 2 
 3 public class Student{
 4 
 5     private String name;
 6     private int age;
 7 
 8     public Student() {
 9         super();
10     }
11 
12     public Student(String name, int age) {
13         super();
14         this.name = name;
15         this.age = age;
16     }
17 
18     public String getName() {
19         return name;
20     }
21 
22     public void setName(String name) {
23         this.name = name;
24     }
25 
26     public int getAge() {
27         return age;
28     }
29 
30     public void setAge(int age) {
31         this.age = age;
32     }
33 }
 1 package com.hxl;
 2 
 3 import java.util.Comparator;
 4 import java.util.TreeSet;
 5 
 6 public class Test {
 7     public static void main(String[] args) {
 8         //如果一個方法的參數是接口,那么真實想要的是其實是接口實現類的對象
 9         //這里的對象只用一次,專門定義一個外部類顯得麻煩
10         //匿名內部類可以實現這個需求
11         TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>(){
12             public int compare(Student s1, Student s2) {
13                 // 先讓兩個對象的age屬性做差比較,這個是主要排序條件
14                 int num = s1.getAge() - s2.getAge();
15                 // 若age屬性相同,再比較name屬性(String類本身實現了Comparable接口)
16                 // 即在主要排序條件相同的情況下,次要排序條件起作用
17                 int flag = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
18                 // 返回比較結果
19                 return flag;
20             }
21         });
22         ts.add(new Student("cc", 11));
23         ts.add(new Student("ee", 11));
24         ts.add(new Student("cc", 22));
25         ts.add(new Student("aa", 22));
26         ts.add(new Student("bb", 11));
27 
28         for (Student s : ts) {
29             System.out.println(s.getName()+"_"+s.getAge());
30         }
31     }
32 }

 【注】開發中會用最后一種,因為第一種只有固定的排序方式,第二種每次都要定義外面類顯得麻煩。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM