Java 對象數組多屬性條件排序問題(詳解)__Java

來源:互聯網
上載者:User
最近遇到了一道多條件排序題,類似於“something有A,B,C三個屬性,先比較A,A條件相同時再比較B,B條件相同時再比較C,排序輸出”的形式。這類題目用C/C++解決起來會很順手,可以用結構體,結合sort和compare,就能完成整個思路。但是我們如何用Java來解決這個問題呢。Java是物件導向的語言,沒有結構體的概念,我們應該定義類。 比方說,用一個球隊排名問題來舉例子。 現在對象是球隊資訊Info,有四個屬性:球隊名name、球隊的積分x、淨勝球y、進球數z。那麼我們這樣定義類:
class Info {private String name;private int x;private int y;private int z;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getx() {return x;}public void setx(int x) {this.x = x;}public int gety() {return y;}public void sety(int y) {this.y = y;}public int getz() {return z;}public void setz(int z) {this.z = z;}}

每一個屬性相應分別有get和set兩個方法,簡要解釋一下,比方說name屬性的setName( ) 方法,作用是設定名稱,我們在主函數裡對對象的name屬性進行賦值時就需要調用它,通過具體的參數值告訴程式你把他設定成什麼名稱,這是不需要傳回值的,也就是定義類型是void的原因;那麼getName( )方法,作用就是擷取名稱了,它不需要參數,程式把name通過傳回值傳回來,所以它的傳回值類型是string。剩餘幾個舉一反三即可,原理一樣。
那麼下面的問題是,主函數怎麼寫。 我們考慮最複雜的一種情況,就是首先輸入資料群組數N,然後依次輸入每組資料,每組屬性裡均包含對象的四個屬性,這裡就要用到對象數組來實現,引入對象數組a [ ] , a[ i ] 中依次存入第 i 組資料對象的四個屬性。接著,把對象數組add到集合b中,這樣做方便我們進行多屬性的條件排序。

                Scanner sc = new Scanner(System.in);int N = sc.nextInt();String temp = sc.nextLine(); // 輸入N後按斷行符號鍵會被讀成nextline,如果這裡不用temp過濾掉這個斷行符號鍵,對下面會有一定影響Info[] a = new Info[N+1];List<Info> b = new ArrayList();for (int i = 0; i < N; i++) {String str = sc.nextLine();String[] s = str.split(" ");a[i] = new Info(); //這一行很重要a[i].setName(s[0]);a[i].setx(Integer.parseInt(s[1]));a[i].sety(Integer.parseInt(s[2]));a[i].setz(Integer.parseInt(s[3]));b.add(a[i]);}


剩下的問題是,怎樣實現多屬性的排序,假設我們這樣規定:先比較積分x,如果積分x相同則比較淨勝球y,如果積分x、淨勝球y都相同則比較進球數z。剛剛我們已經將對象數組存在了集合裡,其實下面很簡單,運用Collections.sort和Comparator就可以解決:


Collections.sort(b, new Comparator<Info>() {public int compare(Info team1, Info team2) {int x = team1.getx() - team2.getx();int y = team1.gety() - team2.gety();int z = team1.getz() - team2.getz();if (x == 0) { if (y == 0) { return z; }return y;}return x;}});

現在我們再去考慮一種複雜一點的,假設我們把規定改為:先比較積分x,積分x高者名次在前,如果積分x相同則比較淨勝球y,淨勝球y多者名次在前,如果積分x、淨勝球y都相同則比較進球數z,進球數多者名次在前。也就是說,我們需要講這些多屬性多條件進行降序排序,應該如何修改上面的代碼呢。思考一下再進行參考:

Collections.sort(b, new Comparator<Info>() {public int compare(Info team1, Info team2) {int x = team1.getx() - team2.getx();int y = team1.gety() - team2.gety();int z = team1.getz() - team2.getz();if (x != 0) {return x > 0 ? -1:1;}if (y != 0) {return y > 0 ? -1:1;}return z > 0 ? -1:1;}});

再延伸一點,很多題目會出現要求當前面的屬性x,y,z都相同時,按照球隊名稱字典序排列。其實這也不難,在上面的基礎上加幾行就可以:

Collections.sort(b, new Comparator<Info>() {public int compare(Info team1, Info team2) {int x = team1.getx() - team2.getx();int y = team1.gety() - team2.gety();int z = team1.getz() - team2.getz();if (x != 0) {return x > 0 ? -1:1;}if (y != 0) {return y > 0 ? -1:1;}if(z!=0) {return z > 0 ? -1:1;}return team1.name.compareTo(team2.name);}});

最後,我們假設這裡只要求輸出排序後的球隊名稱:

for (Info result : b) {System.out.println(result.getName());}

整個思路就都完成了。

另外還需要提一點,我們的main函數是static靜態,但是我們定義的類Info預設屬於內部動態類,這會導致調試的時候出錯,所以在完善程式的時候,我們可以把類也定義成static。最後整理一下全部思路是這樣的:(按照提到的第二種降序輸出)

import java.util.*;public class Main {static class Info {private String name;private int x;private int y;private int z;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getx() {return x;}public void setx(int x) {this.x = x;}public int gety() {return y;}public void sety(int y) {this.y = y;}public int getz() {return z;}public void setz(int z) {this.z = z;}}@SuppressWarnings("unchecked")public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();String temp = sc.nextLine();Info[] a = new Info[N+1];List<Info> b = new ArrayList();for (int i = 0; i < N; i++) {String str = sc.nextLine();String[] s = str.split(" ");a[i] = new Info();a[i].setName(s[0]);a[i].setx(Integer.parseInt(s[1]));a[i].sety(Integer.parseInt(s[2]));a[i].setz(Integer.parseInt(s[3]));b.add(a[i]);}Collections.sort(b, new Comparator<Info>() {public int compare(Info team1, Info team2) {int x = team1.getx() - team2.getx();int y = team1.gety() - team2.gety();int z = team1.getz() - team2.getz();if (x != 0) {return x > 0 ? -1:1;}if (y != 0) {return y > 0 ? -1:1;}if(z!=0) {return z > 0 ? -1:1;}return team1.name.compareTo(team2.name);}});for (Info result : b) {System.out.println(result.getName());}}}

現在假設我們的輸入資料是這樣的:


那麼以上程式的最終運行結果為:





聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.