Java 物件陣列多屬性條件排序問題(詳解)
最近遇到了一道多條件排序題,類似於“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;
}
}
那麼下面的問題是,主函式怎麼寫。
我們考慮最複雜的一種情況,就是首先輸入資料組數N,然後依次輸入每組資料,每組屬性裡均包含物件的四個屬性,這裡就要用到物件陣列來實現,引入物件陣列a [ ] , a[ i ] 中依次存入第 i 組資料物件的四個屬性。接著,把物件陣列add到集合b中,這樣做方便我們進行多屬性的條件排序。
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
String temp = sc.nextLine(); // 輸入N後按Enter鍵會被讀成nextline,如果這裡不用temp過濾掉這個Enter鍵,對下面會有一定影響
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());
}
}
}
現在假設我們的輸入資料是這樣的:
那麼以上程式的最終執行結果為:
相關文章
- 陣列物件按物件某個屬性排序陣列物件排序
- 陣列多重篩選條件排序方法陣列排序
- JS 陣列(Arrey)屬性以及方法詳解JS陣列
- Java 物件排序詳解Java物件排序
- 物件陣列排序物件陣列排序
- Java 多維陣列遍歷詳解Java陣列
- Js陣列物件的屬性值升序排序,並指定陣列中的某個物件移動到陣列的最前面JS陣列物件排序
- mysql json陣列內物件屬性 多個值搜尋MySqlJSON陣列物件
- 面試題:陣列按列排序的問題面試題陣列排序
- 關於陣列的物件獲取及排序問題/小程式的多層頁面返回問題陣列物件排序
- 認識JavaScript陣列物件的length屬性JavaScript陣列物件
- 多維陣列排序陣列排序
- 合併陣列物件中相同的屬性值陣列物件
- NumPy 陣列屬性陣列
- Java break、continue 詳解與陣列深入解析:單維陣列和多維陣列詳細教程Java陣列
- Vector用陣列下標訪問的條件陣列
- java陣列的問題Java陣列
- vue 陣列和物件渲染問題Vue陣列物件
- Laravel 條件陣列 in 的用法Laravel陣列
- PHP 多維陣列排序PHP陣列排序
- JavaScript 陣列 length 屬性JavaScript陣列
- Javascript中的陣列物件排序JavaScript陣列物件排序
- js如何判斷物件的屬性值是物件還是陣列JS物件陣列
- linux多執行緒-----同步物件(互斥量、讀寫鎖、條件變數)的屬性Linux執行緒物件變數
- PHP 字串陣列按照拼音排序的問題PHP字串陣列排序
- 陣列物件根據物件中指定的屬性去重?你知道多少陣列物件
- C++ 獲取陣列大小、多維陣列操作詳解C++陣列
- JavaScript中陣列Array.sort()排序方法詳解JavaScript陣列排序
- Vue 改變陣列中物件的屬性不重新渲染View的解決方案Vue陣列物件View
- 篩選出陣列中屬性為true的每條資料陣列
- 前端進階課程之物件屬性特性詳解前端物件
- Vue路由物件屬性 .meta $route.matched詳解Vue路由物件
- leetcode題解(陣列問題)LeetCode陣列
- Excel不同列多條件計數Excel
- 根據陣列中物件進行排序陣列物件排序
- 陣列物件的去重然後排序陣列物件排序
- Java陣列排序和查詢Java陣列排序
- Lesson4——NumPy 陣列屬性陣列