【天然排序】java
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 }
【比較器排序(外部類實現)】ide
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 }
【比較器排序(內部類實現,若是隻使用一次的話)】this
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 }
【注】開發中會用最後一種,由於第一種只有固定的排序方式,第二種每次都要定義外面類顯得麻煩。spa