[英]How to sort arraylist by mutiple level fields in Java
Class Activity{
private int level;
private Activity predecessor;
}
我的程序創建Activity
實例,將它們放入Arraylist中,並按兩個字段level
和predecessor
對它們進行排序。 首先比較前身。
例如,如果predecessor
不為null
,則當前活動的predecessor Activity
應該是第一個,然后是第二個。 在滿足predecessor
條件之后,可以按level
對以下命令進行排序。
List<Activity> activities = new ArrayList<Activity>();
//Add some activities.
activities.add(Activity);
activities.add(Activity);
Collections.sort(activities,getActivityComparator());
private Comparator<Activity> getActivityComparator() {
return new Comparator<Activity>() {
public int compare(Activity act1, Activity act2) {
if (act1 == null) {
if (act2 == null) {
return 0; // Both activities are null
} else {
return -1; // act1 is NULL, so put act1 in the end of
// the sorted list
}
} else {
if (act2 == null) {
return 1;
}
}
Activity preAct2 = act2.getPredecessor();
if(preAct2!=null&&preAct2==act1)
return -1;
//Adding this by Joeri Hendrickx's suggestion
Activity preAct1 = act1.getPredecessor();
if(preAct1!=null&&preAct1==act2)
return 1;
return act2.getLevel()-act1.getLevel();
}
};
}
我已經編寫了上面的代碼並進行了很多測試,但是如果我將不同的順序放入Arrarylist中,它會輸出不定順序。 所以絕對這是實現此問題的錯誤方法。 似乎根本原因不是每兩個元素都進行了比較。 說Activity act1> Activity act2(按級別條件),Activity act2> Activity act3(按級別條件),並不表示Activity act1> Activity act3(按先前條件)。
在這里,我提出了一個新的想法,即使用冒泡排序而不是使用Collection的接口排序。 它將比較不需要比較器的每兩個元素。 你怎么想?
誰能幫我?
問題在於您的比較器未描述正確的對稱和傳遞關系。
請考慮以下三個對象:
act1{predecessor:null, level:1}
act2{predecessor:act1, level:1}
act3{predecessor:null, level:0}
act4{predecessor:act2, level:2}
現在,在comp是您的比較器的地方, comp(act1, act2)
將返回-1,但是comp(act2, act1)
將返回0。這不是對稱的 。
comp(act1, act2)
comp(act2, act4)
將返回-1, comp(act1, act4)
將返回-1,但是comp(act1, act4)
將返回1。這不是可傳遞的 。
比較器必須描述正確的反身 , 對稱和及物關系才能起作用。
看到Axtaxt的帖子后進行了編輯:此處描述的問題無法通過常規排序來解決,因為始終可以構造一個場景,根據這些規則,您可以在排序層次結構中獲得一個循環。 因此,僅憑此數據就不可能創建可傳遞比較器。
據我了解,由於以下循環的可能性(粗線-上級,細線-大於),您根本無法使比較器具有傳遞性:
因此,您有部分訂單,通用排序算法不適用於此處。
如果只需要在同一活動的后續活動中按級別訂購,則可以使用以下簡單算法來實現:
建立一個從Activity
到其直接后繼的多圖
用以下屬性構建樹:
null
活動
可以使用以下算法創建它:
null
的根節點 比較器的compare方法定義為:“比較其兩個自變量的順序。當第一個自變量小於,等於或大於第二個自變量時,返回負整數,零或正整數。”
這意味着如果希望act1在null時結束,則必須返回一個正整數-> act1更大-> act1將在結尾。 您將正整數和負整數混合在一起。
if (act1 == null) {
if (act2 == null) {
return 0; // Both activities are null
} else {
return 1; // act1 is NULL, so put act1 in the end of
// the sorted list
}
} else {
if (act2 == null) {
return -1;
}
}
同樣,出於相同的原因,您將需要使用
return act1.getLevel()-act2.getLevel();
為比較器成像以接收2和3的整數。您希望它返回負整數,因為第一個參數小於第二個參數。 -> arg1-arg2 = -1而不是arg2-arg1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.