簡體   English   中英

如何根據另一個ArrayList排序ArrayList?

[英]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以在右側進行操作(我個人比較喜歡用左側斷開關系)。 最后,如果要使用label1label2 ,則需要將值復制回(排序后)。 就像是,

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM