Интерфейс Java Comparator используется для сортировки массива или списка объектов на основе пользовательского порядка сортировки. Пользовательский порядок элементов накладывается путем реализации метода comparator's compare() в объектах.
1. Когда использовать интерфейс компаратора
Интерфейс Java Comparator накладывает общий порядок на объекты, которые могут не иметь желаемого естественного порядка.
Например, для объектов List of Employee естественный порядок может быть упорядочен по идентификатору сотрудника. Но в реальных приложениях мы можем захотеть отсортировать список сотрудников по их имени, дате рождения или просто по любому другому подобному критерию. В таких условиях нам нужно использовать интерфейс Comparator.
Интерфейс Comparator можно использовать в следующих ситуациях.
- Сортировка массива или списка объектов, но НЕ в естественном порядке.
- Сортировка массива или списка объектов, где мы не можем изменить исходный код для реализации интерфейса Comparable.
- Использование группировки путем сортировки списка или массива объектов по нескольким различным полям.
2. Переопределение метода compare()
Чтобы включить полное упорядочивание объектов, нам нужно создать класс, реализующий интерфейс Comparator. Затем нам нужно переопределить его метод compare(T o1, T o2).
Compare() сравнивает два аргумента для порядка. Он возвращает отрицательное целое число, ноль или положительное целое число, если первый аргумент меньше, равен или больше второго.
Разработчик также должен гарантировать, что отношение является транзитивным:((compare(x, y)>0) &&(compare(y, z)>0)) подразумевает compare(x, z)>0.
Для заданного класса Employee можно задать порядок по имени сотрудника, создав Comparator, как показано ниже.
импорт java.util.Comparator;открытый класс NameSorter реализует Comparator<Employee>{@Переопределитьpublic int compare(Сотрудник e1, Сотрудник e2) {вернуть e1.getName().compareToIgnoreCase( e2.getName() );}}
импорт java.time.LocalDate;публичный класс Сотрудник {частный длинный идентификатор;личное имя строки;частная LocalDate дата рождения;}
3. Использование компаратора с
3.1 Коллекции.сорт() и Массивы.сорт()
- Используйте метод Collections.sort(list, Comparator) для сортировки списка объектов в порядке, заданном предоставленным экземпляром компаратора.
- Используйте метод Arrays.sort(array, Comparator) для сортировки массива объектов в порядке, заданном предоставленным экземпляром компаратора.
3.2.Коллекции.сравнение()
Этот метод утилиты принимает функцию, которая извлекает ключ сортировки для класса. По сути, это поле, по которому будут сортироваться объекты класса.
//Order by nameComparator.comparing(Employee::getName);//Order by name in reverse orderComparator.comparing(Employee::getName).reversed();//Order by id fieldComparator.comparing(Employee::getId);//Order by employee ageComparator.comparing(Employee::getDate);
3.3.Коллекции.затемСравнение()
Этот метод утилиты используется для группировки по сортировке. Используя этот метод, мы можем связать несколько компараторов для сортировки списка или массива объектов по нескольким полям.
Это очень похоже на предложение SQL GROUP BY для упорядочивания строк по разным полям.
//Order by name and then by ageComparator.comparing(Employee::getName).thenComparing(Employee::getDob);//Order by name -> date of birth -> idComparator.comparing(Employee::getName).thenComparing(Employee::getDob).thenComparing(Employee::getId);
Используя приведенный выше синтаксис, мы можем создать практически любую логику сортировки.
3.4.Коллекции.reverseOrder()
Этот служебный метод возвращает компаратор, который применяет обратный естественный порядок или полный порядок к коллекции объектов, реализующих интерфейс Comparable.
//Reverse of natural order as specified in//Comparable interface's compareTo() methodComparator.reversed();//Reverse of order by nameComparator.comparing(Employee::getName).reversed();
3.5 Другие классы коллекций
Компараторы также могут использоваться для управления порядком определенных структур данных(таких как отсортированные наборы или отсортированные карты ), чтобы обеспечить упорядочение, которое не является естественным порядком.
SortedSet<Employee> sortedUniqueEmployees = new TreeSet<Employee>(new NameSorter());
4. Примеры компараторов Java
4.1 Сортировка списка пользовательских объектов
Пример Java для сортировки списка сотрудников по имени с помощью Comparator.
ArrayList<Employee> list = new ArrayList<>();//Sort in reverse natural orderCollections.sort(list, new NameSorter());
4.2 Сортировать список в обратном порядке
Пример Java для сортировки списка сотрудников по имени с использованием Comparator в обратном порядке.
ArrayList<Employee> list = new ArrayList<>();Collections.sort(list, Comparator.comparing( Employee::getName ).reversed());
4.3 Группировка по сортировке
Пример Java для сортировки списка сотрудников по нескольким полям, т.е. поле за полем.
ArrayList<Employee> list = new ArrayList<>();Comparator<Employee> groupByComparator = Comparator.comparing(Employee::getName).thenComparing(Employee::getDob).thenComparing(Employee::getId);Collections.sort(list, groupByComparator);
5. Заключение
В этом уроке мы узнали об интерфейсе Comparator фреймворка коллекций Java. Он помогает наложить общий порядок на объекты без каких-либо изменений в исходном коде этого класса.
Мы научились сортировать списки и массивы пользовательских объектов. Мы также научились делать обратную сортировку и реализовывать группировку по сортировке в Java.