[英]How to sort ArrayList according to another ArrayList?
我有兩個ArrayList<JLabel>
:
ArrayList<JLabel> label1 = new ArrayList<JLabel>();
ArrayList<JLabel> label2 = new ArrayList<JLabel>();
label1
包含名稱(例如“ John”或“ car”), label2
包含評分(例如“ 8.5”或“ 10.0”)。 我想按評分對兩個列表進行排序。
我用過Collections.sort(label2, new Sort());
對label2
進行排序,但是我不知道如何以相同的方式對label1
進行排序(使用label2
對象)。 這是我的Comparator
類:
class Sort implements Comparator<JLabel>{
public int compare(JLabel o1, JLabel o2) {
Double a = Double.parseDouble(o1.getText());
Double b = Double.parseDouble(o2.getText());
return b.compareTo(a);
}
}
有任何想法嗎?
鑒於您在兩個列表之間沒有定義關系,我認為您應該考慮將兩個值包裝在一個類中:
class Foo {
private String name;
private double rating;
public Foo(String name, double rating){
this.name = name;
this.rating = rating;
}
// getters & setters
}
然后,您可以具有List<Foo>
並根據rating的值對列表進行排序。
在Java 8中,這就像調用sort()
方法一樣簡單,該方法現在在List
提供,並傳入了lambda表達式。
讓我們使用Map
解決這個問題。 首先,我們將定義一個比較器,以按值對降序進行排序,如下所示:
class NumericComparator extends Comparator {
Map map;
public NumericComparator(Map map) {
this.map = map;
}
public int compare(Object o1, Object o2) {
return ((Integer) map.get(o2)).compareTo((Integer) map.get(o1));
}
}
我們將名稱定義為鍵,將等級定義為值。 像這樣:
Map<String, Double> carMap = new HashMap<>();
//we can populate the map like so:
carMap.put("John", 10d); //works nicely in loops
然后,我們獲取該未排序的映射,並將其所有值插入到TreeMap
,該NumericComparator
實現我們之前定義的NumericComparator
。
NumericComparator nc = new NumericComparator(carMap);
Map<String, Double> sortedMap = new TreeMap(nc);
sortedMap.putAll(carMap);
首先,請編程到List
界面。 接下來,我假設你可以使用Apache庫,有Pair<L, R>
在Apache的百科全書琅 (或者你可以實現自己的元組類;或者使用其他類似這一個 )。 無論如何,您都需要修改“ Comparator
以在右側進行操作(我個人比較喜歡用左側斷開關系)。 最后,如果要使用label1
和label2
,則需要將值復制回(排序后)。 就像是,
List<JLabel> label1 = new ArrayList<>();
List<JLabel> label2 = new ArrayList<>();
// ...
List<Pair<JLabel, JLabel>> pairs = new ArrayList<>();
int len = label1.size();
if (len == label2.size()) {
for (int i = 0; i < len; i++) {
pairs.add(Pair.of(label1.get(i), label2.get(i)));
}
Collections.sort(pairs, new Comparator<Pair<JLabel, JLabel>>() {
@Override
public int compare(Pair<JLabel, JLabel> o1,
Pair<JLabel, JLabel> o2) {
double a = Double.parseDouble(o1.getRight().getText());
double b = Double.parseDouble(o2.getRight().getText());
int ret = Double.compare(a, b);
if (ret != 0) {
return ret;
} // if ret is 0, it's a tie.
return o1.getLeft().getText()
.compareTo(o2.getLeft().getText());
}
});
// ... only if you need to use label1 and label2 after the sort.
for (int i = 0; i < len; i++) {
label1.set(i, pairs.get(i).getLeft());
label2.set(i, pairs.get(i).getRight());
}
}
這是一個好問題-在棋盤游戲應用中按擲骰子排序玩家順序時,也給我帶來了麻煩。
將兩個列表綁定到一個新的總對象或一個映射中(所有字符串都是唯一的)的先前答案很好。
但是,如果您確實想要更簡單的方法,那么這里是。
我最初是這樣做的,但沒有引用原始比較列表的深層副本,並且它得到了一些排序權和一些奇怪的條目的混合。 。 。 最終,我看到了曙光,對原始列表做了一個深拷貝(label11)。 還應確保將排序代碼放入私有方法中,以便通過sort Comparator的重寫compare(..)方法訪問兩個列表label11和label2。
. . . .
. . . .
ArrayList<JLabel> label1 = new ArrayList<JLabel>(); // String list
ArrayList<JLabel> label2 = new ArrayList<JLabel>(); // Double list
System.out.println("Original String list : " + label1); // Check original list
sortByValue(label1, label2); // Sort label1 by label2 order descending
System.out.println("Sorted String list: " + label1); // Check sorted list
. . . .
. . . .
/** Private static method to facilitate access to list being sorted and
* the list used as a sort criterion by the code in the sort Comparator's
* overriding compare(..) method. */
private static void sortByValue(ArrayList<JLabel> label1,
ArrayList<JLabel> label2)
{
ArrayList<JLabel> label11 =
new ArrayList<JLabel>(label1); // Deep copy original string list
Collections.sort(list1, new Comparator<JLabel>()
{
@Override
public int compare(JLabel x, JLabel y)
{
return // Sort by descending label2 values
(Double.parseDouble(label2.get(label11.indexOf(y)).getText())
-Double.parseDouble(label2.get(label11.indexOf(x)).getText()))
.intValue();
}
});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.