最近寫水題,很多都是要實現:按A字段降序排序,若相同則按B字段升序排序。利用JAVA的Comparable接口可以很輕易的實現。很多博客在寫重寫compareTo方法時,都只是說 "大於返回1 小於返回-1 相等返回0",這樣的描述看得讓人不知所云,自己親自實踐後,發現這些博客寫的都有瑕疵,於是自己寫下這篇博客,以後方便查閱。可能有些人沒基礎,所以我會從簡單的講起。
1、使用哪個方法實現排序?
在JAVA中可以通過下面兩種自帶方法實現排序 :
//對數組排序
Arrays.sort(待排序數組)
//對列表排序
Collections.sort(待排序列表);
實際上我們查看Collections.sort()的源碼可以發現,它也是複用了Arrays.sort()函數(畢竟數組列表可以相互轉化):
default void sort(Comparator<? super E> c) {
Object[] a = this.toArray(); //先轉化爲數組
Arrays.sort(a, (Comparator) c); //再排序
ListIterator<E> i = this.listIterator();
for (Object e : a) {
i.next();
i.set((E) e);
}
}
2、對要排序的對象數組/列表裏的對象要有什麼要求?
想要排序,必須要先實現Comparable接口,並重寫compareTo方法。可以查看Arrays.sort()的源碼,其就是通用將對像轉換成Comparable,再利用compareTo 函數來判斷對象排序的先後順序。
class Test implements Comparable<Test>{
@Override
public int compareTo(Test another) {
......
}
}
3、如何自定義升/降序?
通過實現compareTo方法,我們可以比較靈活的定製按某某字段升序或降序,甚至可以實現按A降序,A相同時,按B升序的需求。顯然,compareTo返回的是個int值,且在源碼中,Arrays.sort()使用compareTo函數,只關心其符號:
1、小於0 2、大於0 3、等於0
在接下來的代碼裏,小於0用-1表示,大於0用1表示。
如何定義返回值?要看你是升序還是降序:
- 升序排序
大於 another對象 返回1
小於 another對象 返回-1
等於another對象 返回0 - 降序排序
大於 another對象 返回-1
小於 another對象 返回1
等於another對象 返回0
舉例:現有Test類,其含有(int)score、(String)name兩個字段,現要求按score降序排序;若score相等,則按name升序排序。
class Test implements Comparable<Test>{
int score;
String name;
public Test(int score, String name) {
this.score = score;
this.name = name;
}
@Override
public int compareTo(Test another) {
//score按降序
if (this.score > another.score){
return -1;
}else if (this.score < another.score){
return 1;
}else {//成績相等
//按名字升序
if (this.name.compareTo(another.name) > 0){
return 1;
}else if (this.name.compareTo(another.name) < 0){
return -1;
}else {//名字相等
return 1;
}
}
}
@Override
public String toString() {
return "Test{" +
"score=" + score +
", name='" + name + '\'' +
'}';
}
}
測試:
public static void main(String[] args) {
Test[] tests = new Test[]{new Test(100,"b"),new Test(100,"a"),new Test(95,"c")};
Arrays.sort(tests);
for (int i = 0; i < tests.length; i++) {
System.out.println(tests[i]);
}
}
//測試結果
Test{score=100, name='a'}
Test{score=100, name='b'}
Test{score=95, name='c'}