Сортировка объектов в ArrayList по дате?
Каждый пример, который я нахожу, касается алфавитного подхода, в то время как мои элементы сортируются по дате.
Мой ArrayList содержит объекты, для которых одна из камер данных является объектом DateTime. На DateTime я могу вызвать функции:
lt() // less-than
lteq() // less-than-or-equal-to
Поэтому для сравнения я мог бы сделать что-то вроде:
if(myList.get(i).lt(myList.get(j))){
// ...
}
Что мне делать внутри блока if?
Ответы
Ответ 1
Вы можете сделать свой объект сопоставимым:
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 не является нулевым на момент сравнения. Разумно обращаться с нулем, чтобы избежать 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());
}
});
Ответ 2
Так как Java 8 интерфейс List обеспечивает sort. В сочетании с выражением lambda самым простым решением было бы
// 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()))
Ответ 3
Вы можете использовать метод 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 equals
return 0;
else
return 1;
}
});
Обратите внимание: если myList имеет сопоставимый тип (тот, который реализует интерфейс Comparable) (например, Date, Integer или String), вы можете опустить компаратор, и будет использоваться естественный порядок.
Ответ 4
list.sort(Comparator.comparing(o -> o.getDateTime()));
Лучший ответ IMHO из Tunaki с использованием Java 8 lambda
Ответ 5
Учитывая 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;
}
});
Ответ 6
Вот как я решил:
Collections.sort(MyList, (o1, o2) -> o1.getLastModified().compareTo(o2.getLastModified()));
Надеюсь, он вам поможет.
Ответ 7
С введением 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));
Ответ 8
Все ответы здесь я обнаружил, что не обязательно сложны для простой проблемы (по крайней мере, опытному разработчику Java, которого я не знаю). У меня была аналогичная проблема, и я столкнулся с этим (и другими) решениями, и хотя они предоставили указатель, для новичка я нашел, как указано выше. Мое решение зависит от того, где в объекте ваша дата, в этом случае дата является первым элементом Object [], где dataVector - это ArrayList, содержащий ваши объекты.
Collections.sort(dataVector, new Comparator<Object[]>() {
public int compare(Object[] o1, Object[] o2) {
return ((Date)o1[0]).compareTo(((Date)o2[0]));
}
});
Ответ 9
DateTime.compare?
Ответ 10
Это может быть старый ответ, но я использовал некоторые примеры из этого сообщения, чтобы создать компаратор, который сортировал бы ArrayList
из HashMap<String, String>
одним объектом в списке, являющимся меткой времени.
У меня есть следующие объекты:
ArrayList<Map<String, String>> alList = new ArrayList<Map<String, String>>();
Объекты карты выглядят следующим образом:
Map<String, Object> map = new HashMap<>();
// of course this is the actual formatted date below in the timestamp
map.put("timestamp", "MM/dd/yyyy HH:mm:ss");
map.put("item1", "my text goes here");
map.put("item2", "my text goes here");
Это сопоставление - это то, что я использую для загрузки всех моих объектов в список массивов с помощью функции alList.add(map)
в пределах цикла.
Теперь я создал свой собственный компаратор:
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
public class DateSorter implements Comparator {
public int compare(Object firstObjToCompare, Object secondObjToCompare) {
String firstDateString = ((HashMap<String, String>) firstObjToCompare).get("timestamp");
String secondDateString = ((HashMap<String, String>) secondObjToCompare).get("timestamp");
if (secondDateString == null || firstDateString == null) {
return 0;
}
// Convert to Dates
DateTimeFormatter dtf = DateTimeFormat.forPattern("MM/dd/yyyy HH:mm:ss");
DateTime firstDate = dtf.parseDateTime(firstDateString);
DateTime secondDate = dtf.parseDateTime(secondDateString);
if (firstDate.isAfter(secondDate)) return -1;
else if (firstDate.isBefore(secondDate)) return 1;
else return 0;
}
}
Теперь я могу просто вызвать Компаратор в любое время в массиве, и он будет сортировать мой массив, давая мне последнюю временную метку в позиции 0 (верхняя часть списка) и самая ранняя временная метка в конце списка. Новые сообщения попадают в начало в основном.
Collections.sort(alList, new DateSorter());
Это может помочь кому-то, поэтому я разместил его. Учитывайте операторы return в функции compare(). Существует 3 типа результатов. Возврат 0, если они равны, возвращает > 0, если первая дата предшествует второй дате и возвращает < 0, если первая дата после второй даты. Если вы хотите, чтобы ваш список был отменен, просто переключите эти два оператора возврата! Простой =]
Ответ 11
Используйте приведенный ниже подход, чтобы определить даты сортировки или нет
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");
}
}
Ответ 12
Класс Date уже реализует интерфейс Comparator. Предполагая, что у вас есть класс ниже:
public class A {
private Date dateTime;
public Date getDateTime() {
return dateTime;
}
.... other variables
}
List<A> aList
, у вас есть список объектов 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())
Ответ 13
Передайте аргумент ArrayList In.
private static void order(ArrayList<Object> list) {
Collections.sort(list, new Comparator() {
public int compare(Object o2, Object o1) {
String x1 = o1.Date;
String x2 = o2.Date;
return x1.compareTo(x2);
}
});
}