简体   繁体   English

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

[英]Java Sort a list based on another list

I have an ArrayList of the following type: 我有以下类型的ArrayList:

class Move
{
    int from, to;
}

The from property always has a value. from属性始终具有一个值。 The to property will have -1 if it is not set. 如果未设置,则to属性的值为-1。 I have the following array: 我有以下数组:

int[][] history = new int[50][50];

where the dimensions correspond to the 'from' and 'to' of the move class. 尺寸对应于移动类别的“从”和“至”。 In my search function, and depending on certain conditions I need to do: 在搜索功能中,根据某些条件,我需要执行以下操作:

List<move> moves = board.getMoves();
for (int i = 0; i < moves.size(); i++)
    history[move.from][move.to]++;

Because move.to could also be -1, should I increase the dimension of the 2d array 1 and then do: 因为move.to也可以是-1,所以我应该增加2d数组1的尺寸,然后执行以下操作:

history[move.from+1][move.to+]++;

Also, based on the above move list and history array, I need to sort the move list in descending order depending on the counter of the corresponding history index. 另外,基于上面的移动列表和历史记录数组,我需要根据相应历史记录索引的计数器以降序对移动列表进行排序。

Is this possible? 这可能吗?

您可以在Comparator的实现中使用Collections.sort(List,Comparator) ,它将按您希望的顺序进行排序。

Yes, you can make your comparator that uses the history array. 是的,您可以使您的比较器使用历史记录数组。 As an example, I sort my list of int according to an other array counts . 例如,我根据其他数组counts对我的int列表进行排序。

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.addAll(Arrays.asList(new Integer[]{0, 1, 2, 3, 4, 5}));
    final int[] counts = new int[] {3, 4, 1, 7, 0, 1};

    Collections.sort(list, new Comparator<Integer>() {

        @Override
        public int compare(Integer arg0, Integer arg1) {
            return counts[arg1] - counts[arg0];
        }
    });

    System.out.println(list);
}

Outputs: [3, 1, 0, 2, 5, 4] 输出: [3, 1, 0, 2, 5, 4] 3、1、0、2、5、4 [3, 1, 0, 2, 5, 4]

Your compare would be something like: 您的compare将类似于:

@Override
public int compare(Move move0, Move move2) {
    return history[move1.from+1][move1.to] - history[move0.from+1][move0.to];
}

You can setup history as a HashMap or separate class to make this easier. 您可以将历史记录设置为HashMap或单独的类,以使其更容易。 But because you also like to be able to sort history based on frequency, I would recommend a History class: 但是,由于您还希望能够根据频率对历史记录进行排序,因此我建议您使用History类:

class Move {

   int from, to;

   @Override
   public int hashCode() {
      return from + (to * 100);
   }

   @Override
   public boolean equals(Object o) {
      return (o instanceof Move
              && ((Move) o).from == from
              && ((Move) o).to == to);
   }
}

class History extends Move implements Comparable<History> {

   int frequency;

   public History(Move m) {
      from = m.from;
      to = m.to;
      frequency = 1;
   }

   public void increment() {
      frequency += 1;
   }

   public int compareTo(History h) {
      // to be able to sort it in a TreeSet descending on frequency
      // note that it is not resorted if you change frequencies, so 
      // build the set, and then convert it to a TreeSet afterwards.
      return (frequency == h.frequency) ? 1 : (h.frequency - frequency);
   }
}

Then create a HashMap to quickly fill history, and convert it into a TreeSet to sort: 然后创建一个HashMap以快速填充历史记录,并将其转换为TreeSet进行排序:

  List<Move> moves = board.getMoves();
  HashMap<History, History> fillTable = new HashMap<History, History>();
  for (Move m : moves) {
     History h = fillTable.get(m);
     if (h == null) {
        h = new History(m);
        fillTable.put(h, h);
     } else {
        h.increment();
     }
  }
  TreeSet<History> sorted = new TreeSet<History>(fillTable.values());
  .... ready to use

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

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