簡體   English   中英

如何在Java中按多個級別字段對arraylist進行排序

[英]How to sort arraylist by mutiple level fields in Java

Class Activity{
    private int level;
    private Activity predecessor;
}

我的程序創建Activity實例,將它們放入Arraylist中,並按兩個字段levelpredecessor對它們進行排序。 首先比較前身。

例如,如果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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM