Интерфейсы comparable и comparator на Java

Выпуск JDK 8 полностью изменил способ сравнения объектов и их сортировки в Java. Новые функции языка Java 8, например, лямбда-выражение и ссылка на метод, упростили реализацию как компаратора, так и сопоставимого интерфейса, так как вам не нужен анонимный класс для встроенной реализации. Теперь вы можете создавать компараторы всего в одной строке, используя лямбды и ссылку на метод, как мы увидим в этой статье.

Другие функции, такие как предоставление стандартных и статических методов на интерфейсах, также имеют огромное значение, когда дело доходит до компаратора. Они помогли разработчику JavaAPI перепроектировать и развить существующие интерфейсы, что ранее было невозможно без разрушения существующих клиентов этих интерфейсов.

Выпуск JDK 8 добавил много полезных изменений в классы, которые вы используете в своем повседневном программировании, такие как List, Map, Collection, Iterable и Comparator. Java.util.Comparator-один из самых удачливых классов в JDK 8, он получил множество новых мощных методов, которые полностью изменили способ сравнения объектов.

Например, с помощью метода comparing() легче сравнивать объекты в любом конкретном поле, а с помощью метода thenComparing() можно легко связать несколько компараторов, чтобы обеспечить более реалистичное, но сложное упорядочение.

Он также предоставляет несколько полезных методов для изменения порядка компаратора, сортировки объектов в естественном порядке и обеспечения безопасности компаратора null путем упорядочения null либо и первой, либо последней позиции с помощью методов nullsFirst() и nullsLast ().

Написание компаратора с использованием Лямбда-выражения

При изучении Java 8 первое, что должен усвоить разработчик Java, — это реализация интерфейсов SAM с использованием лямбда-выражений. Поскольку Comparator и Comparable также являются интерфейсами SAM, например, они содержат только один абстрактный метод, такой как compare() и compareTo (), вы можете легко реализовать их с помощью лямбда-выражения.

Например, если вы хотите написать Компаратор для сортировки книг по их автору, вы можете написать так, как в следующем примере:

Comparator<Book>byAuthor = (b1, b2) ->b1.getAuthor().compareTo(b2.getAuthor());

Просто сравните это со старым способом написания компаратора Java SE 7 на Java:

Comparator<Book>byAuthorOldWay = new Comparator<Book>() {
publicint compare(Book b1, Book b2) {
return b1.getAuthor().compareTo(b2.getAuthor());
}
};

Вы можете видеть, что в Java 8 вы можете написать компаратор, используя лямбда-выражение всего в одной строке. Теперь вы можете отсортировать список книг с помощью этого компаратора либо с помощью метода Collections.sort (), либо с помощью недавно добавленного метода List.sort (), который сортирует список на месте, как показано ниже:

listOfBooks.sort(byAuthor);
System.out.println(«список книг после сортировки:» + listOfBooks);

Это приведет к печати следующих выходных данных:

список книг после сортировки: [
Book [название=Java Concurrency in Practice, автор=Брайан Гетц, цена=42],
Book [название=Java SE 8 для Действительно нетерпеливых, автор=Cay S. Horstmann, цена=34],
Book [название=Core Java, автор=Cay S. Horstmann, цена=32],
Book [название=Эффективная Java, автор=Джошуа Блох, цена=32],
Book[название=JavaPuzzlers, автор=Джошуа Блох, цена=22]
]

Вы можете видеть, что книга Брайана Гетца возглавляет список, потому что «Б» идет первым в лексикографическом порядке, за ним следует книга Кэя С. Хорстмана и, наконец, книги Джоша Блоха.

Написание компаратора с использованием ссылки на метод

Когда вы просто получаете доступ к свойству объекта в лямбда-выражении, вы можете заменить ссылку на лямбду ссылкой на метод. Это приводит к более чистому и удобочитаемому коду, чем вы когда-либо видели в Java. Например, мы можем написать Компаратор предыдущего примера, используя ссылку на метод, как показано ниже:

Comparator<Book>byAuthor = Comparator.comparing(Book::getAuthor);

Таким образом, очень легко создать еще один компаратор для сортировки по различным параметрам, например, давайте создадим компаратор, который также сортирует byTitle и byPrice:

Comparator<Book>byTitle = Comparator.comparing(Book::getTitle);
Comparator<Book>byPrice = Comparator.comparing(Book::getPrice);

Когда дело доходит до сортировки, вы также можете напрямую передать компаратор методу Collections.sort() или List.sort (), как показано в следующем примере:

listOfBooks.sort(Comparator.comparing(Book::getPrice));
System. out.println («список книг после сортировки по цене:» + listOfBooks);

Выход

список книг после сортировки по цене: [
Book [название=Java и головоломок, автор=Джошуа Блох, цена=22],
Book [название=эффективная Java, автор=Джошуа Блох, цена=32],
Book [название=ядре Java, автор=С. Кей Хорстманн, цена=32],
Book [название=Java на SE 8 для очень нетерпеливых, автор=Кей С. Хорстманн, цена=34],
Book [название=в Java параллелизм на практике, автор=Брайан Гетц, цена=42]

Разница между Comparator и Comparable в Java

Comparator и Comparable — это два интерфейса в Java API, которые используются для сравнения двух объектов в Java. Хотя оба они используются для сравнения, между ними есть некоторые различия, которые нужно знать. Основное различие между Comparable и Comparator заключается в том, что первый используется для определения естественного порядка объекта, например лексикографического порядка для java.lang.String, while later используется для определения любого альтернативного порядка для объекта.

Основное использование java.lang.Comparable и java.util.Comparator– это сортировка списка объектов в Java. Например, чтобы отсортировать список сотрудников по их идентификатору, мы можем использовать Comparator интерфейс и предоставить дополнительную возможность сортировки, мы можем определить несколько компараторов, например AgeComparator для сравнения возраста сотрудника, SalaryComparator для сравнения заработной платы сотрудников и т. д.

Comparator vs Comparable в Java

  1. Интерфейс компаратора находится в пакете java.util, что означает, что это служебный класс, в то время как Comparable интерфейс хранится в пакете java.lang, что означает, что он необходим для объектов Java.
  2. Основываясь на синтаксисе, одно из различий между Comparable и Comparator в Java заключается в том, что Comparable дает нам compareTo (ObjecttoCompare) и принимает объект, который теперь использует дженерики начиная с Java 1.5, в то время как Comparator определяет метод compare(Object obj1, Object obj2) для сравнения двух объектов.
  3. Продолжение предыдущего различия между Comparator vs Comparable. Второй используется для сравнения текущего объекта, представленного этим ключевым словом, с другим объектом, в то время как Comparator сравнивает два произвольных объекта, переданных методу compare() в Java.
  4. Одно из ключевых различий между Comparator и Comparable интерфейсом в Java заключается в том, что вы можете иметь только одну реализацию compareTo() для объекта, в то время как вы можете определить несколько компараторов для сравнения объектов по различным параметрам, например, для объекта Employee, вы можете использовать метод compareTo() для сравнения сотрудников по идентификатору, известному как естественный порядок, в то время как метод multiple compare() для заказа сотрудника по возрасту, зарплате, имени и городу. Также рекомендуется объявлять Comparator как вложенные статические классы в Java, поскольку они тесно связаны с объектами, которые они сравнивают.
  5. Многие классы Java, которые используют Comparator и Comparable(по умолчанию Comparable) предоставляют перегруженный метод для работы с произвольным экземпляром Comparator. Например,Collections.sort() метод, который используется для сортировки коллекции в Java, имеет две реализации, одна из которых сортирует объект на основе естественного порядка, т. е. с помощью java.lang.Comparable и другой, который принимает реализацию java.util.Comparator интерфейс.

Примечание: еще одна ключевая вещь, которая не является разницей, но стоит помнить, что оба метода compareTo() и compare() в Java должны быть согласованы с реализацией equals (), то есть если два метода равны по методу equals (), то compareTo() и compare() должны возвращать ноль. В противном случае ваш объект может нарушить инварианты классов коллекций Java, которые полагаются на compare() или compareTo (), например TreeSet и TreeMap.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *