Java - Class fields sort by Collections Class and Comparator interface

看了一下collection的部分,裡面能夠定義的項目除了我們使用的基本型態外,也可以存放物件

,而物件在我們定義它的類別時,會定義很多的欄位(fields),因此當我們要比較兩兩物件是依

據其中一個欄位來達到排序的效果,可以用到Collections Class的sort,而用到它的sort method,

就必須去實作一個comparator來定義您要排序的欄位為何。

基本上,以簡單的成績單為例子,首先自訂Transcript Class

class Transcript{
   private String name;
   private int Chinese;
   private int Math;
   private int English;
   public Transcript(String name, int Chinese, int Math, int English) {
      super();
      this.name = name;
      this.Chinese = Chinese;
      this.Math = Math;
      this.English = English;
   }
   public String getName() {
      return name;
   }
   public int getChinese() {
      return Chinese;
   }
   public int getMath() {
      return Math;
   }
   public int getEnglish() {
      return English;
   }
}

再來就是定義一個實作了Comparator的類別,如下:
class TranCompare implements Comparator<Transcript>{
   private TranSortCommand state;
   private String methodName;
   public TranCompare(TranSortCommand state, String methodName){
     this.state = state;
     this.methodName = methodName;
   }
   @Override
   public int compare(Transcript o1, Transcript o2) {
   // TODO Auto-generated method stub
   try{
     Method method1 = o1.getClass().getDeclaredMethod(this.methodName);
     Method method2 = o2.getClass().getDeclaredMethod(this.methodName);
     Object obj1 = method1.invoke(o1);
     Object obj2 = method2.invoke(o2);
     if(state == TranSortCommand.NameSort){
         return obj1.toString().compareTo(o2.toString());
     }else{
         if((int)obj1 > (int)obj2){
            return -1;
         }else if((int)obj1 == (int)obj2){
            return 0;
         }else{
            return 1;
         }
     }
   }catch(Exception e){
       e.printStackTrace();
   } 
   return 0;
  }
}
TranSortCommand是一個利用enum自訂的型態,程式碼如下:
public enum TranSortCommand{
    MathSort, EnglishSort, ChineseSort, NameSort
}

目的是讓 if 做判斷時能夠不以數字來表示要做哪一個項目的排序,使其較具有可讀性。

而透過reflect來呼叫我在Transcript declared的method,使得在分數的排序上,讓相同的判斷

只寫一次就好了,如此我們就要在new TranCompare給予要做哪一個項目的排序及method的

名稱,而排序字串的部分可以return String compareTo method結果,在Collections Class sort也是

有作用的。

再來是主程式的部分:

public class TestComparableInterface {
 public static void main(String[] args) {
    // TODO Auto-generated method stub
    List<Transcript> students = new ArrayList<Transcript>();
    Transcript t1 = new Transcript("Ben", 87, 91, 80);
    Transcript t2 = new Transcript("sjkok", 94, 99, 65);
    Transcript t3 = new Transcript("Aaron", 44, 55, 100);
    Transcript t4 = new Transcript("zhibin", 77, 88, 66);
    students.add(t1);
    students.add(t2);
    students.add(t3);
    students.add(t4);
    Collections.sort(students, new TranCompare(TranSortCommand.MathSort, "getMath"));
    //Collections.reverse(students);
    for(Transcript t : students){
     System.out.println("Name:"+t.getName()+"\tChinese:"+t.getChinese()+"\tMath:"+t.getMath()+"\tEnglish:"+t.getEnglish());
    }
 }
}

透過Collections.sort,帶進List and 您定義的comparator,如此再印出資料時就可以達到某項目

排序的效果!如下:



留言