Научитесь сортировать ArrayList в Java с помощью ArrayList.sort(), Collections.sort(), интерфейса Comparator и потоков Java 8. Мы можем использовать те же методы для сортировки в естественном порядке, а также в обратном порядке элементов, хранящихся в ArrayList.
1. Различные способы сортировки ArrayList
ArrayList — это упорядоченная и несортированная коллекция элементов, которая является частью фреймворка Java Collections, подобно другим классам, таким как LinkedList или HashSet. По умолчанию элементы, добавленные в ArrayList, сохраняются в том порядке, в котором они были вставлены.
Когда нам нужно отсортировать элементы в ArrayList, мы можем использовать следующие методы:
Метод сортировки | Когда использовать |
---|---|
ArrayList.сортировать() | Для сортировки на месте, т.е. изменяет исходный arraylist. |
Коллекция.сорт() | Внутренне использует ArrayList.sort() без дополнительных преимуществ. |
Arraylist.stream.sorted() | Не изменяет исходный список и возвращает новый отсортированный массив. Предоставляет возможность выполнять другие операции над элементами потока. |
Все вышеперечисленные методы по умолчанию сортируют элементы в естественном порядке, т.е. в порядке возрастания. Мы можем использовать поставку пользовательского порядка экземпляра Comparator для пользовательского порядка, например Collections.reverseOrder() для обратного порядка элементов.
2. Обеспечение порядка сортировки элементов
Для любого объекта, который необходимо хранить и сортировать в естественном порядке, без использования Comparator, мы должны реализовать интерфейс Comparable и написать логику для сравнения двух экземпляров. Чтобы продемонстрировать пример сортировки, мы сохраним экземпляры Task.
Естественно, порядок сортировки сортирует задачи по полю идентификатора.
public record Task(long id, String name, boolean status)implements Comparable<Task> {@Overridepublic int compareTo(Task other) {return Long.compare(other.id, this.id);}}
Для индивидуального упорядочивания мы можем создать экземпляры Comparator, имеющие соответствующую логику сортировки. Например, мы можем сортировать задачи по полю имени. Компараторы полезны, когда элемент(который должен быть сохранен в списке) не реализует интерфейс Comparable.
Comparator<Task> nameSorter = Comparator.comparing(Task::name);Comparator<E> reverseSorter = Comparator.reverseOrder();
Наконец, для демонстрации мы создаем массив с 5 задачами следующим образом:
//Create ArrayListArrayList<Task> arrayList = new ArrayList<>();//Add itemsarrayList.add(new Task(1, "One", true));arrayList.add(new Task(2, "Two", false));arrayList.add(new Task(3, "Three", true));arrayList.add(new Task(4, "Four", false));arrayList.add(new Task(5, "Five", true));
2. Сортировка ArrayList в естественном(возрастающем) порядке
Функция sort() является частью интерфейса List и реализована в классе ArrayList с версии Java 8. Она принимает экземпляр Comparator, используемый для обеспечения порядка сортировки.
Обратите внимание, что метод ArrayList.sort() выполняет сортировку на месте, т.е. изменяет исходный список.
arrayList.sort(Comparator.naturalOrder());
Вывод программы:
[Task[id=1, name=One, status=true],Task[id=2, name=Two, status=false],Task[id=3, name=Three, status=true],Task[id=4, name=Four, status=false],Task[id=5, name=Five, status=true]]
Для сортировки в обратном порядке мы можем использовать Comparator.reverseOrder(), который возвращает компаратор, устанавливающий обратный естественному порядок.
arrayList.sort(Comparator.reverseOrder());
Вывод программы:
[Task[id=5, name=Five, status=true],Task[id=4, name=Four, status=false],Task[id=3, name=Three, status=true],Task[id=2, name=Two, status=false],Task[id=1, name=One, status=true]]
Аналогичным образом мы можем применить пользовательскую сортировку, используя также пользовательский компаратор.
arrayList.sort(Comparator.comparing(Task::name));
Вывод программы выводит задачи в порядке сортировки по именам.
[Task[id=5, name=Five, status=true],Task[id=4, name=Four, status=false],Task[id=1, name=One, status=true],Task[id=3, name=Three, status=true],Task[id=2, name=Two, status=false]]
3. Сортировка ArrayList с помощью Collection.sort()
Collection.sort() работает очень похоже на List.sort(). Фактически, внутри он использует метод list.sort(), поэтому рекомендуется использовать List.sort() вместо Collections.sort().
public static <T> void sort(List<T> list, Comparator<? super T> c) {list.sort(c);}
Для справки рассмотрим пример кода использования метода Collections.sort():
//Natural orderCollections.sort(arrayList);//Reverse orderCollections.sort(arrayList, Comparator.reverseOrder());//Custom orderCollections.sort(arrayList, Comparator.comparing(Task::name));
4. Сортировка ArrayList с использованием потоков Java 8
Использование потоков Java дает возможность применять другие промежуточные операции к отсортированным элементам в том же операторе.
Потоки еще более полезны, когда мы не хотим изменять исходный массив, а хотим временно отсортировать список и выполнить некоторые операции над отсортированными элементами.
//Natural orderList<Task> sortedList = arrayList.stream().sorted().toList();//Reverse orderList<Task> sortedList = arrayList.stream().sorted(Comparator.reverseOrder()).toList();
Следующий пример объединяет операцию фильтра с операцией сортировки элементов потока. Он выбирает только активные задачи, сортирует задачи по имени и собирает элементы в новый список.
//Sorting with filteringList<Task> list = arrayList.stream().filter(t -> t.status()).sorted(Comparator.comparing(Task::name)).toList();
Вывод программы:
[ Task[id=5, name=Five, status=true],Task[id=1, name=One, status=true],Task[id=3, name=Three, status=true]]
5. Заключение
В заключение можно сказать, что сортировка arraylist проста и легка в большинстве случаев. Для конкретных случаев полезно знать требования и использовать индивидуальное решение:
- Реализуйте интерфейс Comparable для естественного упорядочивания и используйте экземпляры Comparator для пользовательского и обратного упорядочивания.
- Используйте List.sort(), если мы хотим изменить исходную коллекцию.
- Используйте Streams, если мы не хотим изменять исходную коллекцию.
- Использование Collections.sort() не дает никаких преимуществ, поэтому его можно избежать.