按ID排序对象的顺序与ids列表相同

时间:2013-10-02 08:50:45

标签: android sorting

我有整数ID列表。让我们说这个列表是ArrayList<Integer>或int [],没关系。我有另一个ArrayList<Obj>包含具有相同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 个答案:

答案 0 :(得分: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 :(得分: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);
}

然后你需要使用一个使用Object和ref表的id的Comparator对你的第二个列表进行排序:

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

答案 2 :(得分:0)

当他发布时,我正在写Etienne的答案,所以只是为了好玩这里是一个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快一点,但你必须分析两个答案。