Я использую этот класс для демонстрации:
public class CarDataTransferObject {
private static final DateTimeFormatter DATE_FORMATTER
= DateTimeFormatter.ofPattern("dd-MMM-yyyy", Locale.ENGLISH);
LocalDate manufacturedDate;
public CarDataTransferObject(String manufacturedDateString) {
if (manufacturedDateString == null) {
manufacturedDate = null;
} else {
manufacturedDate = LocalDate.parse(manufacturedDateString, DATE_FORMATTER);
}
}
// getter, toString, …
}
Для сортировки по возрастанию:
List<CarDataTransferObject> carList = Arrays.asList(
new CarDataTransferObject("23-Sep-2018"),
new CarDataTransferObject(null),
new CarDataTransferObject("04-Jul-2018"),
new CarDataTransferObject("11-Aug-2018"),
new CarDataTransferObject(null),
new CarDataTransferObject("30-May-2018"));
carList.sort(Comparator.comparing(
CarDataTransferObject::getManufacturedDate,
Comparator.nullsLast(Comparator.naturalOrder())));
carList.forEach(System.out::println);
Вывод:
Car manufactured 30-May-2018
Car manufactured 04-Jul-2018
Car manufactured 11-Aug-2018
Car manufactured 23-Sep-2018
Car (no manufactured date)
Car (no manufactured date)
Для сортировки по убыванию:
carList.sort(Comparator.comparing(
CarDataTransferObject::getManufacturedDate,
Comparator.nullsFirst(Comparator.reverseOrder())));
Вывод:
Car (no manufactured date)
Car (no manufactured date)
Car manufactured 23-Sep-2018
Car manufactured 11-Aug-2018
Car manufactured 04-Jul-2018
Car manufactured 30-May-2018
java.time и другие советы
Используйте LocalDate
из java.time, современного Java-API даты и времени, для васдата изготовления.Не используйте строки.LocalDate
- это дата без времени суток, так что вам нужно здесь.Форматируйте дату только в строку для представления пользователю или для сериализации.java.time встроен в Java из Java 8 (и также перенесен в Java 6 и 7).
Статические методы в интерфейсе Comparator
также добавлены в Java 8 - comparing
, nullsFirst
и многое другое - сделать построение довольно сложных компараторов не только более простым и кратким, но и менее подверженным ошибкам.
Что пошло не так в вашем коде?
Вам необходимо явно обрабатывать нули,Метод sort может выбирать любые сравнения, которые ему нравятся (на практике он является детерминистическим, который он использует, но не рассчитывает на то, что сможет его просмотреть).Таким образом, если ваш список содержит объект с null
датой, он может сравнивать любые два (или более) других объекта с объектом с нулевым значением.Каждое сравнение дает 0, поэтому сортировка теперь «знает» (неправильно), что все эти объекты принадлежат одному месту в сортировке.Сортировка стабильна, это означает, что все эти объекты выходят в том же порядке, в каком они были в списке перед сортировкой.
Вместо этого сообщите методу сортировки, хотите ли вы нулевые значения первым или последним, и вы получите то, чтоВы просите.
Ссылка
Учебное пособие по Oracle: Дата и время , объясняющее, как использовать java.time
.