Сортировать объекты в ArrayList по дате? - PullRequest
127 голосов
/ 08 мая 2011

Каждый пример, который я нахожу, касается этого по алфавиту, в то время как мои элементы сортируются по дате.

Мой ArrayList содержит объекты, для которых одна из камер данных является объектом DateTime.В DateTime я могу вызывать функции:

lt() // less-than
lteq() // less-than-or-equal-to

Поэтому для сравнения я могу сделать что-то вроде:

if(myList.get(i).lt(myList.get(j))){
    // ...
}

Что мне делать внутри блока if?

Ответы [ 12 ]

379 голосов
/ 08 мая 2011

Вы можете сделать свой объект сопоставимым:

public static class MyObject implements Comparable<MyObject> {

  private Date dateTime;

  public Date getDateTime() {
    return dateTime;
  }

  public void setDateTime(Date datetime) {
    this.dateTime = datetime;
  }

  @Override
  public int compareTo(MyObject o) {
    return getDateTime().compareTo(o.getDateTime());
  }
}

А потом вы сортируете по телефону:

Collections.sort(myList);

Однако иногда вы не хотите менять свою модель, например, когда вы хотите отсортировать по нескольким различным свойствам. В этом случае вы можете создать компаратор на лету:

Collections.sort(myList, new Comparator<MyObject>() {
  public int compare(MyObject o1, MyObject o2) {
      return o1.getDateTime().compareTo(o2.getDateTime());
  }
});

Однако вышеприведенное работает только в том случае, если вы уверены, что dateTime не является нулевым во время сравнения. Целесообразно также обрабатывать null, чтобы избежать исключений NullPointerExceptions:

public static class MyObject implements Comparable<MyObject> {

  private Date dateTime;

  public Date getDateTime() {
    return dateTime;
  }

  public void setDateTime(Date datetime) {
    this.dateTime = datetime;
  }

  @Override
  public int compareTo(MyObject o) {
    if (getDateTime() == null || o.getDateTime() == null)
      return 0;
    return getDateTime().compareTo(o.getDateTime());
  }
}

Или во втором примере:

Collections.sort(myList, new Comparator<MyObject>() {
  public int compare(MyObject o1, MyObject o2) {
      if (o1.getDateTime() == null || o2.getDateTime() == null)
        return 0;
      return o1.getDateTime().compareTo(o2.getDateTime());
  }
});
47 голосов
/ 18 мая 2016

Начиная с Java 8, интерфейс List предоставляет метод sort . В сочетании с выражением лямбда самым простым решением будет

// sort DateTime typed list
list.sort((d1,d2) -> d1.compareTo(d2));
// or an object which has an DateTime attribute
list.sort((o1,o2) -> o1.getDateTime().compareTo(o2.getDateTime()));
// or like mentioned by Tunaki
list.sort(Comparator.comparing(o -> o.getDateTime()))
18 голосов
/ 08 мая 2011

Вы можете использовать метод Collections.sort. Это статический метод. Вы передаете это список и компаратор. Он использует модифицированный алгоритм сортировки слиянием по списку. Вот почему вы должны передать ему компаратор для сравнения пар.

Collections.sort(myList, new Comparator<MyObject> {
   public int compare(MyObject o1, MyObject o2) {
      DateTime a = o1.getDateTime();
      DateTime b = o2.getDateTime();
      if (a.lt(b)) 
        return -1;
      else if (a.lteq(b)) // it's equals
         return 0;
      else
         return 1;
   }
});

Обратите внимание, что если myList имеет сопоставимый тип (тот, который реализует интерфейс Comparable) (например, Date, Integer или String), вы можете опустить компаратор, и будет использовано естественное упорядочение.

9 голосов
/ 13 июня 2017
list.sort(Comparator.comparing(o -> o.getDateTime()));

Лучший ответ ИМХО от Тунаки с использованием Java 8 lambda

7 голосов
/ 08 мая 2011

Учитывая MyObject, который имеет DateTime член с методом getDateTime(), вы можете отсортировать ArrayList, который содержит MyObject элементы, по DateTime объектам, например так:

Collections.sort(myList, new Comparator<MyObject>() {
    public int compare(MyObject o1, MyObject o2) {
        return o1.getDateTime().lt(o2.getDateTime()) ? -1 : 1;
    }
});
4 голосов
/ 19 ноября 2015

Вот как я решил:

Collections.sort(MyList, (o1, o2) -> o1.getLastModified().compareTo(o2.getLastModified()));

Надеюсь, это поможет вам.

2 голосов
/ 06 января 2015

С появлением Java 1.8 потоки очень полезны для решения таких проблем:

Comparator <DateTime> myComparator = (arg1, arg2) 
                -> {
                    if(arg1.lt(arg2)) 
                       return -1;
                    else if (arg1.lteq(arg2))
                       return 0;
                    else
                       return 1;
                   };

ArrayList<DateTime> sortedList = myList
                   .stream()
                   .sorted(myComparator)
                   .collect(Collectors.toCollection(ArrayList::new));
1 голос
/ 09 сентября 2012

Все ответы, которые я нашел здесь, оказались неоправданно сложными для простой задачи (по крайней мере, для опытного разработчика Java, которым я не являюсь). У меня была похожая проблема, и я случайно наткнулся на это (и другие) решения, и хотя они предоставили указатель, для новичка, которого я нашел, как указано выше. Мое решение зависит от того, где в Объекте ваша Дата находится, в данном случае, дата является первым элементом Объекта [], где dataVector - это ArrayList, содержащий ваши Объекты.

Collections.sort(dataVector, new Comparator<Object[]>() {
    public int compare(Object[] o1, Object[] o2) {
        return ((Date)o1[0]).compareTo(((Date)o2[0]));
    }
});
0 голосов
/ 18 июня 2019

Класс Date уже реализует интерфейс Comparator. Предполагая, что у вас есть класс ниже:

public class A {

    private Date dateTime;

    public Date getDateTime() {
        return dateTime;
    }

    .... other variables

}

И скажем, у вас есть список объектов A как List<A> aList, вы можете легко отсортировать его с помощью потокового API Java 8 (фрагмент ниже):

import java.util.Comparator;
import java.util.stream.Collectors;

...

aList = aList.stream()
        .sorted(Comparator.comparing(A::getDateTime))
        .collect(Collectors.toList())
0 голосов
/ 07 марта 2019

Используйте приведенный ниже подход для определения даты сортировки или нет

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd-MM-yyyy");

boolean  decendingOrder = true;
    for(int index=0;index<date.size() - 1; index++) {
        if(simpleDateFormat.parse(date.get(index)).getTime() < simpleDateFormat.parse(date.get(index+1)).getTime()) {
            decendingOrder = false;
            break;
        }
    }
    if(decendingOrder) {
        System.out.println("Date are in Decending Order");
    }else {
        System.out.println("Date not in Decending Order");
    }       
}   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...