Интерфейс, сопоставимый с Java

Интерфейс 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(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.

Прокрутить вверх