根据另一个列表的值对列表进行排序 - Java

时间:2011-01-29 22:44:51

标签: java sorting

一个名单列表:(未排序)例如 [保罗,犯规,标记]

另一个带整数的列表:例如 [5,2,6]

第二个列表中的值是每个人(名字)“选中”的数字,所以 保罗有5号,犯规数是2,标记数是6。

我正在尝试根据降序排列的第二个列表的值对名称列表进行排序。我不能使用地图,因为我需要在我的程序上的其他场合使用这两个列表。

通过排序方法我我得到这样的列表: [paul,mark,foul]

正如你所看到的,它没有像我想要的那样排序。

正确一个是: [mark,paul,foul]

但我无法找到代码上的错误。

public ArrayList<String> sortNames(ArrayList<Integer> results){
    String tmp;
    for (int k=0; k<Names.size()-1; k++) {

        boolean isSorted=true;
        for (int i=1; i<Names.size()-k; i++) {

             if (results.get(i)>results.get(i-1)  ) {

                tmp=Names.get(i);
                Names.set(i,Names.get(i-1));
                Names.set(i-1,tmp);

                isSorted=false;
            }
        }
        if (isSorted) break;
    }
    return Names;

}

修改!!!在下面的答案的帮助下,代码是:

    public ArrayList<String> sortNames(ArrayList<Integer> results){
        String tmp2;
        int tmp;
        for (int k=0; k<Names.size()-1; k++) {

            boolean isSorted=true;
            for (int i=1; i<Names.size()-k; i++) {

                 if (results.get(i)>results.get(i-1)  ) {
                     tmp=results.get(i);
                     results.set(i,results.get(i-1));
                     results.set(i-1,tmp);


                    tmp2=Names.get(i);
                    Names.set(i,Names.get(i-1));
                    Names.set(i-1,tmp2);

                    isSorted=false;
                }
            }
            if (isSorted) break;
        }
    return Names;

}

此代码正常工作(适用于小型列表) 我只是查询为什么它不适用于像ImageIcon这样的对象。有什么想法吗?

5 个答案:

答案 0 :(得分:6)

摆脱两个列表。如果数据是相关的,那么数据应该一起存储在一个简单的类中。然后将整个类添加到列表中,您可以根据需要对各个属性进行排序。您可以根据需要使用Bean Comparator对此列表进行排序。

答案 1 :(得分:2)

您可以根据List结果的值对List Names进行排序......它只会因条件k<Names.size()-1而终止。在bubblesort中通常根本不需要这样的条件,这表明存在错误。

您必须在两个列表中交换元素,而不仅仅是在名称中。这是答案,但要注意,bubblesort是有史以来最糟糕的算法之一。

编辑:

  

我无法使用地图,因为我需要在我的程序中的其他场合使用这两个列表。

当然可以(假设数字是唯一的):

Map<Integer, String> m = new HashMap<Integer, String>();
for (int i=0; i<results.size(); ++i) m.put(results.get(i), Names.get(i));
Collections.sort(results);
for (int i=0; i<results.size(); ++i) Names.set(i, m.get(results.get(i));

可能存在错误,但这个想法应该是明确的。

还有另一种使用一类对(结果,名称)的解决方案,如果需要,它甚至可以使用非唯一数字。

稍微短一点的解决方案:

Map<Integer, String> m = new TreeMap<Integer, String>();
for (int i=0; i<results.size(); ++i) m.put(results.get(i), Names.get(i));
Names.clear();
Names.addAll(m.values());

这基于TreeSet.values的属性“集合的迭代器按相应键的升序返回值”和List.addAll附加所有指定集合中的元素到此列表的末尾,按指定集合的​​迭代器返回的顺序

答案 2 :(得分:1)

  1. 通过成对地从两个列表中取元素(具有将两个值存储为字段的类)来构建(名称,值)对的列表。实现Comparable以比较值字段。

  2. 使用Collections.sort()对结果进行排序。

  3. 从排序列表中提取名称。

答案 3 :(得分:1)

创建临时映射名称 - >数字,然后使用自定义比较器对名称进行排序,该比较器使用映射:

Map<String, Integer> m = new HashMap<String, Integer>;
for(int i = 0; i < Names.size(); i++)
    m.put(Names.get(i), results.get(i));
Collections.sort(Names, new Comparator<String>() {
    @Override
    public int compare(String s1, s2) { return m.get(s2) - m.get(s1); }
});

即使某些数字相等,此解决方案仍然有效。

答案 4 :(得分:1)

在那里你可以获得你所获得的最快速的快速入口,最简单的原则是:当你交换第一个清单时,你可以随意交换第二个清单。希望这不是作业,但即使它不是...... 简而言之,复制/粘贴并享受quickSort(list1, list2)就是您所需要的。列表按照Comparable定义的第一个自然结构列表进行排序。

private static void swap(List<?> l1, List<?> l2, int i, int j){
    Collections.swap(l1, i, j);
    Collections.swap(l2, i, j);     
}
private static <T extends Comparable<? super T>>  int partition(List<T> comp, List<?> l2, int left, int right){
    int i = left, j = right;
    T pivot = comp.get((left + right) / 2);

    while (i <= j) {
        while (comp.get(i).compareTo(pivot)<0)
            i++;

        while (comp.get(i).compareTo(pivot)>0)
            j--;

        if (i <= j) {
            swap(comp, l2, i++, j--);
        }
    };
    return i;
}
private <T extends Comparable<? super T>>  void quickSort(List<T> comp, List<?> l2, int left, int right) {
    int index = partition(comp, l2, left, right);

    if (left < index - 1)
        quickSort(comp, l2, left, index - 1);

    if (index < right)
        quickSort(comp, l2, index, right);
}

public <T extends Comparable<? super T>>  void quickSort(List<T> comp, List<?> l2) {
    if (comp.size()<l2.size())
        throw new IndexOutOfBoundsException();
    quickSort(comp, l2, 0, comp.size());
}