简体   繁体   English

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

[英]Sorting a list based on another list's values - Java

One list with names:(unsorted) eg [paul, foul, mark] 一个名字列表:(未分类)例如[保罗,犯规,标记]

Another list with integers: eg [5, 2, 6] 另一个带整数的列表:例如[5,2,6]

The values on the second list are the numbers "selected" by each person(name), so paul has number 5, foul's number is 2, mark's number is 6. 第二个列表中的值是每个人(名称)“选择”的数字,因此paul的数字为5,犯规的数字为2,标记的数字为6。

I'm trying to sort the names' list based on the values of the second list on a descending order. 我正在尝试根据降序排列的第二个列表的值对名称列表进行排序。 I cant use a map as i need both lists on other occasions on my program. 我不能使用地图,因为我需要在我的程序上的其他场合使用这两个列表。

With the sorting method i did i get a list like that: [paul, mark, foul] 通过排序方法, 我得到了这样的列表: [paul,mark,foul]

As you can see, its not sorted as i would want. 正如你所看到的,它没有像我想要的那样排序。

The correct one would be: [mark,paul,foul] 正确的是: [马克,保罗,犯规]

But i cant find the fault on the code. 但我无法找到代码上的错误。

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;

}

EDIT!!! 编辑!!! with the help of the answers below,the code is: 在下面的答案的帮助下,代码是:

    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;

}

This code works properly(for small lists) I've just the query why it doesnt work for objects like ImageIcon. 这段代码工作正常(对于小列表)我只是查询为什么它不适用于像ImageIcon这样的对象。 Any ideas? 有任何想法吗?

Get rid of the two Lists. 摆脱两个列表。 If the data is related then the data should be stored together in a simple class. 如果数据是相关的,那么数据应该一起存储在一个简单的类中。 Then the entire class is added to a list where you can sort on the individual properties if required. 然后将整个类添加到列表中,您可以根据需要对各个属性进行排序。 You can use a Bean Comparator to sort this List however you desire. 您可以使用Bean Comparator根据需要对此列表进行排序。

You're sort of sorting the List Names based on values of the List results... and it only terminates because of the condition k<Names.size()-1 . 您可以根据List结果的值对List Names进行排序......它只会因条件k<Names.size()-1终止。 Such a condition is usually not needed at all in bubblesort, which shows that there's something wrong. 在bubblesort中通常根本不需要这样的条件,这表明存在错误。

You'd have to swap elements in both lists, not only in Names. 您必须在两个列表中交换元素,而不仅仅是在名称中。 This is the answer, but be warned that bubblesort is one of the worst algorithms ever. 这是答案,但要注意,bubblesort是有史以来最糟糕的算法之一。

Edit: 编辑:

I cant use a map as i need both lists on other occasions on my program. 我不能使用地图,因为我需要在我的程序上的其他场合使用这两个列表。

For sure you can (assuming the numbers are unique): 你肯定可以(假设数字是唯一的):

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));

There may be errors, but the idea should be clear. 可能存在错误,但这个想法应该是明确的。

There's another solution using a class of pairs (result, name), which works even with non-unique numbers, if you need it. 还有另一种解决方案,使用一对对(结果,名称),如果需要,它甚至可以使用非唯一数字。

A slightly shorter solution: 一个稍短的解决方案:

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());

This is based on properties of TreeSet.values " The collection's iterator returns the values in ascending order of the corresponding keys " and List.addAll " Appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's iterator " 这基于TreeSet.values的属性“ 集合的迭代器按相应键的升序返回值 ”和List.addAll将指定集合中的所有元素 按顺序 添加到此列表的末尾由指定集合的​​迭代器返回

  1. Build a list of pairs of (name, value) by taking elements from the two lists pairwise (having a class that stores the two values as fields). 通过成对地从两个列表中获取元素来构建(名称,值)对的列表(具有将两个值存储为字段的类)。 Implement Comparable to compare the value field. 实现Comparable以比较值字段。

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

  3. Extract the names from the sorted list. 从排序列表中提取名称。

Create a temporary mapping name->number, then sort names with custom comparator which uses the mapping: 创建临时映射名称 - >数字,然后使用自定义比较器对名称进行排序,该比较器使用映射:

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); }
});

This solution will work even if some numbers are equal. 即使某些数字相等,此解决方案也能正常工作。

There you go w/ the vanilest quicksort you'd ever get, the simplest principle is: when you swap the 1st list, swap the 2nd as you go. 在那里,你可以得到你所能获得的最快速的快速入口,最简单的原则是:当你交换第一个清单时,你可以随意交换第二个清单。 Hopefully that's not a homework, but even if it's not... In short, copy/paste and enjoy the quickSort(list1, list2) is all you need. 希望这不是作业,但即使它不是......简而言之,复制/粘贴并享受quickSort(list1, list2)就是你所需要的。 The lists are sorted by the 1st list natural oredering define by Comparable . 列表按照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());
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM