2014年12月14日 星期日

【分享】在Java List中,使用元素(物件)的屬性來排序

你一定在某個時候,曾經把一堆物件放到List後,還需要依物件的某個屬性來做排序。

如下面的theStudents變數裡面放了一堆Student類別的物件,還要依每個學生的分數來做降冪排列:
Student student1 = new Student(1, "Mark", 90);
Student student2 = new Student(2, "Tom", 58);
Student student3 = new Student(3, "Shine", 70);
Student student4 = new Student(4, "Kelly", 88);
Student student5 = new Student(5, "Mark", 60);

List<Student> theStudents = Arrays.asList(student1, 
                                                  student2, 
                                                  student3, 
                                                  student4, 
                                                  student5); 
要達到上列的要求,我可以用java.util.Collections類別中的sort(java.util.List)這個方法來實現,但在Java Doc中有提到,傳入該方法的List物件,其中包含的元件需要支援排序,在實作上要讓其中的元素實作Comparable介面

回到我的例子,若要讓Student類別可以依分收排序,就要讓Student類別實作Comparable介面,並在compareTo中去實作分數比較的邏輯:
package idv.jk.model;

public class Student implements Comparable<Student>
{
 public Student(int id, String name, int score)
 {
  super();
  this.id = id;
  this.name = name;
  this.score = score;
 }

 private int id;
 private String name;
 private int score;
 
 public int getId()
 {
  return id;
 }
 public void setId(int id)
 {
  this.id = id;
 }
 public String getName()
 {
  return name;
 }
 public void setName(String name)
 {
  this.name = name;
 }
 public int getScore()
 {
  return score;
 }
 public void setScore(int score)
 {
  this.score = score;
 }
 
 @Override
 public String toString()
 {
  return "Student [id=" + id + ", name=" + name + ", score=" + score
    + "]";
 }
 
 @Override
 public int compareTo(Student student)
 {
  return this.getScore() <= student.getScore() ? 1 : -1;
 }
}
public int compareTo(Student student)回傳「1」可以想成此物件和其他Student物件比較時,若分數比較小,會往後排;若是回傳「-1」,即分數比較大,則會往前排,達到我要依分數做降冪排列的需求。

依不一樣的需求,可以依所需要的邏輯去實作,詳細的說明可以參考compareTo

再來我就可以寫個程式來驗證我的實作:
package idv.jk.test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import idv.jk.model.Student;

public class SortStudentMain
{
 public static void main(String args[])
 {
  Student student1 = new Student(1, "Mark", 90);
  Student student2 = new Student(2, "Tom", 58);
  Student student3 = new Student(3, "Shine", 70);
  Student student4 = new Student(4, "Kelly", 88);
  Student student5 = new Student(5, "Mark", 60);
  
  List<Student> theStudents = Arrays.asList(student1, 
                                                student2, 
                                                student3, 
                                                student4, 
                                                student5);
  System.out.println("排序前:");
  for(Student s : theStudents)
  {
   System.out.println(s);
  }
  
  Collections.sort(theStudents);
  System.out.println("排序後:");
  for(Student s : theStudents)
  {
   System.out.println(s);
  }
 }
}
執行列出排序前和排序後的結果為:
排序前:
Student [id=1, name=Mark, score=90]
Student [id=2, name=Tom, score=58]
Student [id=3, name=Shine, score=70]
Student [id=4, name=Kelly, score=88]
Student [id=5, name=Mark, score=60]
排序後:
Student [id=1, name=Mark, score=90]
Student [id=4, name=Kelly, score=88]
Student [id=3, name=Shine, score=70]
Student [id=5, name=Mark, score=60]
Student [id=2, name=Tom, score=58]

沒有留言: