[英]Sorting a list based on another list's values - Java
一個名字列表:(未分類)例如[保羅,犯規,標記]
另一個帶整數的列表:例如[5,2,6]
第二個列表中的值是每個人(名稱)“選擇”的數字,因此paul的數字為5,犯規的數字為2,標記的數字為6。
我正在嘗試根據降序排列的第二個列表的值對名稱列表進行排序。 我不能使用地圖,因為我需要在我的程序上的其他場合使用這兩個列表。
通過排序方法, 我得到了這樣的列表: [paul,mark,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這樣的對象。 有任何想法嗎?
擺脫兩個列表。 如果數據是相關的,那么數據應該一起存儲在一個簡單的類中。 然后將整個類添加到列表中,您可以根據需要對各個屬性進行排序。 您可以使用Bean Comparator根據需要對此列表進行排序。
您可以根據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 “ 將指定集合中的所有元素 按順序 添加到此列表的末尾由指定集合的迭代器返回 “
通過成對地從兩個列表中獲取元素來構建(名稱,值)對的列表(具有將兩個值存儲為字段的類)。 實現Comparable以比較值字段。
使用Collections.sort()
對結果進行排序。
從排序列表中提取名稱。
創建臨時映射名稱 - >數字,然后使用自定義比較器對名稱進行排序,該比較器使用映射:
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); }
});
即使某些數字相等,此解決方案也能正常工作。
在那里,你可以得到你所能獲得的最快速的快速入口,最簡單的原則是:當你交換第一個清單時,你可以隨意交換第二個清單。 希望這不是作業,但即使它不是......簡而言之,復制/粘貼並享受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());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.