«1. Обзор
В этом руководстве мы рассмотрим различные способы проверки сортировки списка в Java.
2. Итеративный подход
Итеративный подход — это простой и интуитивно понятный способ проверки отсортированного списка. В этом подходе мы будем повторять список и сравнивать соседние элементы. Если какой-либо из двух соседних элементов не отсортирован, мы можем сказать, что список не отсортирован.
Список может быть отсортирован как в естественном, так и в пользовательском порядке. Мы рассмотрим оба этих случая, используя интерфейсы Comparable и Comparator.
2.1. Использование Comparable
Во-первых, давайте рассмотрим пример списка, элементы которого имеют тип Comparable. Здесь мы рассмотрим список, содержащий объекты типа String:
public static boolean isSorted(List<String> listOfStrings) {
if (isEmpty(listOfStrings) || listOfStrings.size() == 1) {
return true;
}
Iterator<String> iter = listOfStrings.iterator();
String current, previous = iter.next();
while (iter.hasNext()) {
current = iter.next();
if (previous.compareTo(current) > 0) {
return false;
}
previous = current;
}
return true;
}
2.2. Использование Comparator
Теперь давайте рассмотрим класс Employee, который не реализует Comparable. Итак, в этом случае нам нужно использовать Компаратор для сравнения соседних элементов списка:
public static boolean isSorted(List<Employee> employees, Comparator<Employee> employeeComparator) {
if (isEmpty(employees) || employees.size() == 1) {
return true;
}
Iterator<Employee> iter = employees.iterator();
Employee current, previous = iter.next();
while (iter.hasNext()) {
current = iter.next();
if (employeeComparator.compare(previous, current) > 0) {
return false;
}
previous = current;
}
return true;
}
Приведенные выше два примера похожи. Единственная разница заключается в том, как мы сравниваем предыдущий и текущий элементы списка.
Кроме того, мы также можем использовать Компаратор, чтобы иметь точный контроль над проверкой сортировки. Дополнительная информация об этих двух доступна в нашем учебнике Comparator and Comparable in Java.
3. Рекурсивный подход
Теперь мы посмотрим, как проверить отсортированный список с помощью рекурсии:
public static boolean isSorted(List<String> listOfStrings) {
return isSorted(listOfStrings, listOfStrings.size());
}
public static boolean isSorted(List<String> listOfStrings, int index) {
if (index < 2) {
return true;
} else if (listOfStrings.get(index - 2).compareTo(listOfStrings.get(index - 1)) > 0) {
return false;
} else {
return isSorted(listOfStrings, index - 1);
}
}
4. Использование Guava
Вместо этого часто лучше использовать стороннюю библиотеку написания собственной логики. В библиотеке Guava есть несколько служебных классов, которые мы можем использовать для проверки сортировки списка.
4.1. Класс сортировки Guava
В этом разделе мы увидим, как использовать класс Ordering в Guava для проверки отсортированного списка.
Сначала мы рассмотрим пример списка, содержащего элементы типа Comparable:
public static boolean isSorted(List<String> listOfStrings) {
return Ordering.<String> natural().isOrdered(listOfStrings);
}
Далее мы увидим, как мы можем проверить, отсортирован ли список объектов Employee с помощью Comparator: ~~ ~
public static boolean isSorted(List<Employee> employees, Comparator<Employee> employeeComparator) {
return Ordering.from(employeeComparator).isOrdered(employees);
}
Кроме того, мы можем использовать функцию natural().reverseOrder(), чтобы проверить, отсортирован ли список в обратном порядке. Кроме того, мы можем использовать natural().nullFirst() и natural().nullLast(), чтобы проверить, появляется ли null первым или последним в отсортированном списке.
Чтобы узнать больше о классе Guava Ordering, мы можем обратиться к нашему Руководству по статье Guava’s Ordering.
4.2. Класс компараторов Guava
Если мы используем Java 8 или выше, Guava предоставляет лучшую альтернативу с точки зрения класса Comparators. Мы увидим пример использования метода isInOrder этого класса:
public static boolean isSorted(List<String> listOfStrings) {
return Comparators.isInOrder(listOfStrings, Comparator.<String> naturalOrder());
}
Как мы видим, в приведенном выше примере мы использовали естественный порядок для проверки отсортированного списка. Мы также можем использовать компаратор для настройки проверки сортировки.
5. Заключение
В этой статье мы увидели, как мы можем проверить отсортированный список, используя простой итеративный подход, рекурсивный подход и использование Guava. Мы также кратко коснулись использования Comparator и Comparable при определении логики проверки сортировки.
Реализацию всех этих примеров и фрагментов кода можно найти на GitHub.