java集合的工具類Collections中提供了兩種排序的方法,分別是:
- Collections.sort(List list)
- Collections.sort(List list,Comparator c)
第一種稱為自然排序,參與排序的對象需實現comparable接口,重寫其compareTo()方法,方法體中實現對象的比較大小規則,示例如下:
實體類:(基本屬性,getter/setter方法,有參無參構造方法,toString方法)
1 package test; 2 3 public class Emp implements Comparable { 4 5 private String name; 6 private int age; 7 public String getName() { 8 return name; 9 } 10 public void setName(String name) { 11 this.name = name; 12 } 13 public int getAge() { 14 return age; 15 } 16 public void setAge(int age) { 17 this.age = age; 18 } 19 public Emp() { 20 super(); 21 } 22 public Emp(String name, int age) { 23 super(); 24 this.name = name; 25 this.age = age; 26 } 27 @Override 28 public String toString() { 29 return "Emp [name=" + name + ", age=" + age + "]"; 30 } 31 @Override 32 public int compareTo(Object o) { 33 if(o instanceof Emp){ 34 Emp emp = (Emp) o; 35 // return this.age-emp.getAge();//按照年齡升序排序 36 return this.name.compareTo(emp.getName());//換姓名升序排序 37 } 38 throw new ClassCastException("不能轉換為Emp類型的對象..."); 39 } 40 41 }
第二種叫定制排序,或自定義排序,需編寫匿名內部類,先new一個Comparator接口的比較器對象c,同時實現compare()其方法;
然后將比較器對象c傳給Collections.sort()方法的參數列表中,實現排序功能;
說明:第一種方法不夠靈活,實體類實現了comparable接口后,會增加耦合,如果在項目中不同的位置需要根據不同的屬性調用排序方法時,需要反復修改比較規則(按name還是按age),二者只能選擇其一,會起沖突.第二種就很好地解決了這個問題.在需要的地方,創建個內部類的實例,重寫其比較方法即可.
jUnit4單元測試類代碼如下:
1 package test; 2 3 import java.util.ArrayList; 4 import java.util.Collections; 5 import java.util.Comparator; 6 import java.util.List; 7 8 import org.junit.BeforeClass; 9 import org.junit.Test; 10 11 public class TestSort { 12 13 static List list = new ArrayList(); 14 //@BeforeClass注解標注的方法會在其它測試方法執行之前先執行, 15 //且只執行一次.@Before注解標注的方法會在每個測試方法之前執行; 16 //此處初始化集合只需要一次,因此使用@BeforeClass. 17 @BeforeClass 18 public static void init(){ 19 list.add(new Emp("tom",18)); 20 list.add(new Emp("jack",20)); 21 list.add(new Emp("rose",15)); 22 list.add(new Emp("jerry",17)); 23 System.out.println("排序前:"); 24 for(Object o : list){ 25 System.out.println(o); 26 } 27 } 28 29 /**按age升序排序*/ 30 // @Test 31 // public void testSortAge(){ 32 // Collections.sort(list); 33 // System.out.println("自然排序按age排序后:"); 34 // for(Object o : list){ 35 // System.out.println(o); 36 // } 37 // } 38 // 39 /**按name升序排序*/ 40 @Test 41 public void testSortName(){ 42 Collections.sort(list); 43 System.out.println("自然排序按name升序排序后:"); 44 for(Object o : list){ 45 System.out.println(o); 46 } 47 } 48 49 /**使用Comparator比較器按age升序排序*/ 50 @Test 51 public void testComparatorSortAge(){ 52 Collections.sort(list,new Comparator () { 53 @Override 54 public int compare(Object o1, Object o2) { 55 if(o1 instanceof Emp && o2 instanceof Emp){ 56 Emp e1 = (Emp) o1; 57 Emp e2 = (Emp) o2; 58 return e1.getAge() - e2.getAge(); 59 } 60 throw new ClassCastException("不能轉換為Emp類型"); 61 } 62 }); 63 System.out.println("使用Comparator比較器按age升序排序后:"); 64 for(Object o : list){ 65 System.out.println(o); 66 } 67 } 68 /**使用Comparator比較器按name升序排序*/ 69 @Test 70 public void testComparatorSortName(){ 71 Collections.sort(list,new Comparator () { 72 @Override 73 public int compare(Object o1, Object o2) { 74 if(o1 instanceof Emp && o2 instanceof Emp){ 75 Emp e1 = (Emp) o1; 76 Emp e2 = (Emp) o2; 77 return e1.getName().compareTo(e2.getName()); 78 } 79 throw new ClassCastException("不能轉換為Emp類型"); 80 } 81 }); 82 System.out.println("使用Comparator比較器按name升序排序后:"); 83 for(Object o : list){ 84 System.out.println(o); 85 } 86 } 87 88 }
右鍵空白位置 —> Run As —> JUnit Test —>
運行結果如下:
排序前: Emp [name=tom, age=18] Emp [name=jack, age=20] Emp [name=rose, age=15] Emp [name=jerry, age=17] 自然排序按name升序排序后: Emp [name=jack, age=20] Emp [name=jerry, age=17] Emp [name=rose, age=15] Emp [name=tom, age=18] 使用Comparator比較器按age升序排序后: Emp [name=rose, age=15] Emp [name=jerry, age=17] Emp [name=tom, age=18] Emp [name=jack, age=20] 使用Comparator比較器按name升序排序后: Emp [name=jack, age=20] Emp [name=jerry, age=17] Emp [name=rose, age=15] Emp [name=tom, age=18]