Интерфейс Java Comparable является частью Collection Framework. Изучите назначение интерфейса Comparable и используйте его в различных сценариях.
1. Схожий интерфейс
1.1 Зачем внедрять Comparable?
В Java, если мы хотим отсортировать список элементов, то мы можем использовать метод Collections.sort(). Он сортирует элементы списка в соответствии с естественным порядком. Все классы-оболочки Java, классы даты-времени и String и т. д. реализуют интерфейс Comparable, и поэтому у них определен их естественный порядок.
Например, класс java.lang.String имеет лексикографический порядок(или порядок словаря) в качестве своего естественного порядка. Поэтому, если мы отсортируем список объектов String, они будут отсортированы так, как они будут отображаться в словаре. Аналогично, объекты Integer будут отсортированы в порядке возрастания, естественно.
Но нам нужно определить естественный порядок классов пользовательского домена, которые мы создаем в приложении. Например, Employee, Order и т. д. Это необходимо, если мы хотим отсортировать список сотрудников или заказов с помощью метода Collections.sort() или любого другого метода, который ожидает, что элементы списка будут Comparable.
Таким образом, основная цель интерфейса Comparable — определить естественный порядок сортировки классов, которые его реализуют.
1.2. Внедрение сопоставимых
Интерфейс Comparable имеет единственный абстрактный метод compareTo(), который объекты должны реализовать для обеспечения естественного порядка.
- Объекты должны быть взаимно сопоставимы и не должны вызывать исключение ClassCastException для любого ключа в коллекции.
- Метод compareTo() должен возвращать отрицательное целое число, ноль или положительное целое число, поскольку этот объект меньше, равен или больше указанного объекта.
- Обратите внимание, что compareTo() должен выдать исключение, если y.compareTo(x) выдает исключение.
- Кроме того, связь между сравниваемыми объектами должна быть транзитивной, т.е.(x.compareTo(y) > 0 && y.compareTo(z) > 0) подразумевает x.compareTo(z)>0.
- null не является экземпляром какого-либо класса, поэтому e.compareTo(null) должен выдать исключение NullPointerException.
публичный интерфейс Comparable<T>{public int compareTo(T o);}
Например, для класса Employee естественный порядок может быть основан на поле id.
импорт java.time.LocalDate;открытый класс Employee реализует Comparable<Employee> {частный длинный идентификатор;личное имя строки;частная LocalDate дата рождения;@Переопределитьpublic int compareTo(Сотрудник o){вернуть this.getId().compareTo( o.getId() );}}
Используя интерфейс Comparable, мы можем сортировать все типы объектов, включая строки, классы-оболочки или пользовательские объекты.
См. также: Сортировка с помощью Comparable и Comparator
2. Использование сопоставимых
Мы можем сортировать объекты, реализующие интерфейс Comparable, следующими способами:
2.1. Коллекции.сорт() и Массивы.сорт()
- Используйте метод Collections.sort() для сортировки списка объектов.
- Используйте метод Arrays.sort() для сортировки массива объектов.
Collections.sort(items);Arrays.sort(items);
2.2.Коллекции.reverseOrder()
Этот служебный метод возвращает компаратор, который применяет к коллекции объектов порядок, обратный естественному.
Это позволяет использовать простую идиому для сортировки(или обслуживания) коллекций(или массивов) объектов, реализующих интерфейс Comparable в обратном естественном порядке.
Collections.sort(items, Collections.reverseOrder());Arrays.sort(items, Collections.reverseOrder());
2.3 Сортированные коллекции
Объекты, реализующие этот интерфейс, могут использоваться в качестве ключей в отсортированной карте или в качестве элементов в отсортированном наборе(например, TreeSet) без необходимости указывать компаратор.
//All all items are automatically sortedSortedSet<Item> itemsSet = new TreeSet<>();
2.4.Потоки
Stream.sorted() можно использовать для сортировки потока объектов, реализующих интерфейс Comparable. Однако следует отметить, что stream.sorted() не сортирует исходную коллекцию — сортируются только элементы в потоке.
items.stream().sorted().forEach(i -> System.out.println(i);
3. Сравнительные примеры
Все приведенные примеры сортируют списки с помощью метода Collections.sort(). Если нам нужно отсортировать массивы объектов, просто замените Collections.sort() на Arrays.sort().
3.1 Сортировка строк
Программа Java для сортировки списка строк с использованием интерфейса Comparable.
ArrayList<String> list = new ArrayList<>();list.add("E");list.add("A");list.add("C");list.add("B");list.add("D");Collections.sort(list);System.out.println(list);
Вывод программы.
[А, Б, В, Г, Д]
3.2 Сортировка строк в обратном порядке
Программа на Java для сортировки списка строк в обратном порядке с использованием интерфейса Comparable.
ArrayList<String> list = new ArrayList<>();list.add("E");list.add("A");list.add("C");list.add("B");list.add("D");//Sort in reverse natural orderCollections.sort(list, Collections.reverseOrder());System.out.println(list);
Вывод программы.
[E, D, C, B, A]
3.3 Сортировка целых чисел
Программа на Java для сортировки списка целых чисел в естественном и обратном порядке с использованием интерфейса Comparable.
ArrayList<Integer> list = new ArrayList<>();list.add(10);list.add(300);list.add(45);list.add(2);list.add(5);//Natural orderCollections.sort(list);System.out.println(list);//Sort in reverse natural orderCollections.sort(list, Collections.reverseOrder());System.out.println(list);
Вывод программы.
[2, 5, 10, 45, 300][300, 45, 10, 5, 2]
3.4 Сортировка списка пользовательских объектов
В этом примере мы сортируем список сотрудников по идентификатору.
ArrayList<Employee> list = new ArrayList<>();list.add(new Employee(22l, "Lokesh", LocalDate.now()));list.add(new Employee(18l, "Alex", LocalDate.now()));list.add(new Employee(30l, "Bob", LocalDate.now()));list.add(new Employee(600l, "Charles", LocalDate.now()));list.add(new Employee(5l, "David", LocalDate.now()));//Natural orderCollections.sort(list);System.out.println(list);//Sort in reverse natural orderCollections.sort(list, Collections.reverseOrder());System.out.println(list);
Вывод программы.
[Employee [id=5, name=David, dob=2018-10-29],Employee [id=18, name=Alex, dob=2018-10-29],Employee [id=22, name=Lokesh, dob=2018-10-29],Employee [id=30, name=Bob, dob=2018-10-29],Employee [id=600, name=Charles, dob=2018-10-29]]//Reverse sorted[Employee [id=600, name=Charles, dob=2018-10-30],Employee [id=30, name=Bob, dob=2018-10-30],Employee [id=22, name=Lokesh, dob=2018-10-30],Employee [id=18, name=Alex, dob=2018-10-30],Employee [id=5, name=David, dob=2018-10-30]]
4. Заключение
В этом уроке мы узнали об интерфейсе Comparable. Этот интерфейс помогает накладывать естественный порядок на объекты с помощью простой реализации интерфейса. Мы также научились сортировать список строк, массив строк, список целых чисел и массив целых чисел. Мы узнали, как сортировать объекты Employee в Java с помощью Comparable.
Более подробную информацию можно найти в Руководстве по сортировке в Java.