Сортировка коллекции на основе двух параметров одновременно

#java #sorting #collections

#java #сортировка #Коллекции

Вопрос:

У меня есть класс с двумя полями даты, которые говорят:

 class TestData {
    Date activation;
    Date timeStamp;
}
  

Я хочу отсортировать список вышеупомянутого класса на основе activation даты, и если они равны, то на основе timestamp т. е. max (активация) и max (временная метка).

Код, который я пробовал, выглядит следующим образом, который извлекает только max (активация)

 public class CollectionSort {

    public static void main(String[] args) {
        List<TestData> testList = new ArrayList<TestData>();

        Collections.sort(testList, new Comparator<TestData>() {

            @Override
            public int compare(TestData t1, TestData t2) {
                int result = 0;
                if (t1.getActivation().before(t2.getActivation())) {
                        result = 1;
                }
                return resu<
            }
        });
        System.out.println("First object is "   testList.get(0));
    }
}
  

Любая помощь была бы высоко оценена.

Спасибо

Комментарии:

1.Обратите внимание, что если ваша Comparator реализация никогда не может вернуть отрицательное целое число (обычно -1 ), то это почти наверняка неправильно! Потому что если compare(a, b) возвращает положительное значение int , то compare(b, a) должно возвращать отрицательное!

2. Вам не нужны приведения к TestData или instanceof test в вашем методе сравнения. Начиная с generics (Java 5) приведения выполняются автоматически для вас за кулисами, следовательно, параметры метода уже имеют тип TestData.

Ответ №1:

Это сделало бы это.!

         Collections.sort(yourList, new Comparator<TestData>() {    
            public int compare(TestData o1, TestData o2) {
                int date1Diff = o1.getActivation().compareTo(o2.getActivation());
                return date1Diff == 0 ? 
                        o1.geTimestamp().compareTo(o2.getTimestamp()) :
                        date1Diff;
            }               
        });
  

Ответ №2:

Вот как это сделать на обычном Java:

  public int compare(TestData o1, TestData o2) {
    int result = o1.getActivation().compareTo(o2.getActivation()));
    if(result==0) result = o1.getTimeStamp().compareTo(o2.getTimeStamp());
    return resu<
 }
  

Или с помощью Guava (используя ComparisonChain ):

 public int compare(TestData o1, TestData o2) {
    return ComparisonChain.start()
      .compare(o1.getActivation(), o2.getActivation())
      .compare(o1.getTimeStamp(), o2.getTimeStamp())
      .result();
 }
  

Или с помощью Commons / Lang (используя CompareToBuilder ):

 public int compare(TestData o1, TestData o2) {
    return new CompareToBuilder()
      .append(o1.getActivation(), o2.getActivation())
      .append(o1.getTimeStamp(), o2.getTimeStamp())
      .toComparison();
 }
  

(Все три версии эквивалентны, но обычная версия Java является наиболее подробной и, следовательно, наиболее подверженной ошибкам. Все три решения предполагают, что оба o1.getActivation() и o1.getTimestamp() реализуют Comparable ).