2013-10-02 81 views
0

我有整數ID列表。可以說這個列表是ArrayList<Integer>或int [],沒關係。我有另一個ArrayList<Obj>,其中包含與第一個列表中的id相同的對象,但它們按不同的順序排序。通過id按照與ID列表相同的順序排列對象

我想排序第二個列表中的對象作爲第一個列表中的ID。

例:

FIRST LIST: { 1, 5, 4, 8, 6 } 
SECOND LIST: { Obj[id=5], Obj[id=8], Obj[id=6], Obj[id=1], Obj[id=4] } 

RESULT LIST: { Obj[id=1], Obj[id=5], Obj[id=4], Obj[id=8], Obj[id=6] } 

誰能告訴我的(有效)的方式來做到這一點?

回答

3

我會建議使用地圖:

Map<Integer, Obj> map = new HashMap<Integer, Obj>(secondList.size() * 2); 
for (final Obj obj : secondList) { 
    map.put(obj.id, obj); 
} 
for (int i = 0; i < secondList.size(); i++) { 
    secondList.set(i, map.get(firstList.get(i))); 
} 

這運行在O(n),其中恕我直言,幾乎是最好的,你可以得到。

1

A /創建一個匹配的ID索引列表,如:

1 -> 0 
5 -> 1 
4 -> 2 
8 -> 3 
6 -> 4 

這是你的第一個列表的逆參考。它表示每個ID的位置。一個SparseIntArray是這樣做的一個好辦法:

SparseIntArray ref = new SparseIntArray(); 
for (int i = 0; i < firstList.size(); i++) { 
    ref.append(firstList.get(i), i); 
} 

然後,你需要使用一個使用對象的ID和裁判表比較排序你的第二個列表:

Collections.sort(secondList, new Comparator<Obj>() { 
    public int compare(Obj t1, Obj t2) { 
     return ref.get(t1.id) - ref.get(t2.id); 
    } 
}); 
0

我是在寫艾蒂安的答案的中間時,他的貼吧,所以只是爲了好玩這裏是一個O(N^2)以較小的常數因子的解決方案,不會產生任何對象:

int[] first = { 1, 5, 4, 8, 6 }; 
    Obj[] second = { Obj[id=5], Obj[id=8], Obj[id=6], Obj[id=1], Obj[id=4] }; 
    int i = 0; 
    while(i < second.length) { 
     int ind = -1; 
     for(int j=0;j<first.length;j+=1) { 
      if(first[j] == second[i].id) { 
       ind = j; 
       break; 
      } 
     } 
     if(ind == -1) break; //Bad news 
     if(ind == i) { 
      i += 1; 
     } else { 
      Obj temp = second[i]; 
      second[i] = second[ind]; 
      second[ind] = temp; 
     } 
    } 

顯然,第二個[]的創建是僞代碼,但如果數組的長度相等,其餘部分將工作。我認爲對於非常小的數據集,這將比Etienne的要快一些,但是你必須分析兩個答案。

相關問題