Компаратор: Користувацьке Порівняння Даних
Розглянемо другий функціональний інтерфейс — Comparator, дізнаємося, як він реалізує порівняння, а також зрозуміємо різницю між Comparator і Comparable.
Що таке Comparator?
Ключовий метод у функціональному інтерфейсі Comparator:
int compare(T o1, T o2);
Метод compare(T o1, T o2) повертає:
- Від’ємне число, якщо
o1менше заo2; - Нуль, якщо
o1таo2рівні; - Додатне число, якщо
o1більше заo2.
Практичне застосування
Реалізація сортування об'єктів Book із використанням інтерфейсу Comparator. Замість реалізації методу порівняння безпосередньо в класі Book, використовуйте статичні методи інтерфейсу Comparator для визначення логіки сортування.
Main.java
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253package com.example; import java.util.List; import java.util.ArrayList; import java.util.Comparator; public class Main { public static void main(String[] args) { List<Book> books = new ArrayList<>(); books.add(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925)); books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); books.add(new Book("1984", "George Orwell", 1949)); // Sort by title books.sort(Comparator.comparing(Book::getTitle)); System.out.println("Sorted by title: " + books); System.out.println("------------------------"); // Sort by author books.sort(Comparator.comparing(Book::getAuthor)); System.out.println("Sorted by author: " + books); } } class Book { private String title; private String author; private int year; public Book(String title, String author, int year) { this.title = title; this.author = author; this.year = year; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getYear() { return year; } @Override public String toString() { return title + " by " + author + " (" + year + ")"; } }
У цьому прикладі використовується інтерфейс Comparator для сортування списку books. Але чому застосовано метод comparing() замість compare()?
Якщо ви хочете використати метод compare(), необхідно створити Comparator об'єкт та реалізувати метод compare.
public static Comparator<Book> titleComparator = new Comparator<Book>() {
@Override
public int compare(Book b1, Book b2) {
return b1.getTitle().compareTo(b2.getTitle());
}
};
Цей код визначає Comparator<Book> за допомогою анонімного класу для порівняння двох об'єктів Book за їхнім полем title.
Оскільки String реалізує Comparable, для порівняння заголовків лексикографічно використовується метод compareTo(), який повертає від’ємне, нульове або додатне значення.
Альтернативно, того ж результату можна досягти за допомогою лямбда-виразу для більш лаконічної реалізації:
(b1, b2) -> b1.getTitle().compareTo(b2.getTitle());
Але існує ще простiший підхід: використання методу Comparator.comparing(). Цей метод автоматично обробляє логіку порівняння, роблячи її більш читабельною та лаконічною.
Потрібно лише передати посилання на метод, який витягує поле для порівняння.
Comparator.comparing(Book::getTitle)
Метод sort() списку викликає переданий Comparator, який, у свою чергу, визначає порядок елементів шляхом порівняння їх за значеннями, що повертаються вказаними методами.
Багаторівневе сортування
Якщо потрібно сортувати за декількома критеріями, можна використати метод thenComparing:
books.sort(
Comparator.comparing(Book::getYear) // First by year
.thenComparing(Book::getTitle) // Then by title
);
Цей приклад демонструє, як сортувати список книг спочатку за роком їхнього випуску (year), а потім за title. Процес сортування спочатку порівнює книги за полем year, і якщо у двох книг однаковий year, тоді вони порівнюються за title для визначення остаткового порядку.
Зворотне сортування
Зміна порядку сортування в Java корисна, коли потрібно сортувати елементи спочатку за одним критерієм, а потім змінити порядок для наступного критерію.
Методи reversed() та Comparator.reverseOrder() допомагають керувати напрямком сортування, але працюють по-різному.
books.sort(
Comparator.comparing(Book::getYear).reversed() // Sort by year (descending)
.thenComparing(Book::getTitle, Comparator.reverseOrder()) // Then by title (descending)
);
Книги спочатку сортуються за роком випуску у спадному порядку за допомогою reversed(). Якщо декілька книг мають однаковий year, метод thenComparing() сортує їх за title у зворотному алфавітному порядку з використанням Comparator.reverseOrder().
Це гарантує, що найновіші книги відображаються першими, а в межах одного року назви впорядковуються від Z до A.
Відмінності між Comparable та Comparator
Використовуйте інтерфейс Comparable, якщо клас має природний порядок сортування, наприклад, сортування за одним полем. Використовуйте Comparator, коли потрібно сортувати за декількома критеріями або визначити кастомний порядок для об'єктів.
1. Коли слід використовувати інтерфейс Comparable?
2. Коли слід використовувати інтерфейс Comparator?
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Awesome!
Completion rate improved to 2.33
Компаратор: Користувацьке Порівняння Даних
Свайпніть щоб показати меню
Розглянемо другий функціональний інтерфейс — Comparator, дізнаємося, як він реалізує порівняння, а також зрозуміємо різницю між Comparator і Comparable.
Що таке Comparator?
Ключовий метод у функціональному інтерфейсі Comparator:
int compare(T o1, T o2);
Метод compare(T o1, T o2) повертає:
- Від’ємне число, якщо
o1менше заo2; - Нуль, якщо
o1таo2рівні; - Додатне число, якщо
o1більше заo2.
Практичне застосування
Реалізація сортування об'єктів Book із використанням інтерфейсу Comparator. Замість реалізації методу порівняння безпосередньо в класі Book, використовуйте статичні методи інтерфейсу Comparator для визначення логіки сортування.
Main.java
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253package com.example; import java.util.List; import java.util.ArrayList; import java.util.Comparator; public class Main { public static void main(String[] args) { List<Book> books = new ArrayList<>(); books.add(new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925)); books.add(new Book("To Kill a Mockingbird", "Harper Lee", 1960)); books.add(new Book("1984", "George Orwell", 1949)); // Sort by title books.sort(Comparator.comparing(Book::getTitle)); System.out.println("Sorted by title: " + books); System.out.println("------------------------"); // Sort by author books.sort(Comparator.comparing(Book::getAuthor)); System.out.println("Sorted by author: " + books); } } class Book { private String title; private String author; private int year; public Book(String title, String author, int year) { this.title = title; this.author = author; this.year = year; } public String getTitle() { return title; } public String getAuthor() { return author; } public int getYear() { return year; } @Override public String toString() { return title + " by " + author + " (" + year + ")"; } }
У цьому прикладі використовується інтерфейс Comparator для сортування списку books. Але чому застосовано метод comparing() замість compare()?
Якщо ви хочете використати метод compare(), необхідно створити Comparator об'єкт та реалізувати метод compare.
public static Comparator<Book> titleComparator = new Comparator<Book>() {
@Override
public int compare(Book b1, Book b2) {
return b1.getTitle().compareTo(b2.getTitle());
}
};
Цей код визначає Comparator<Book> за допомогою анонімного класу для порівняння двох об'єктів Book за їхнім полем title.
Оскільки String реалізує Comparable, для порівняння заголовків лексикографічно використовується метод compareTo(), який повертає від’ємне, нульове або додатне значення.
Альтернативно, того ж результату можна досягти за допомогою лямбда-виразу для більш лаконічної реалізації:
(b1, b2) -> b1.getTitle().compareTo(b2.getTitle());
Але існує ще простiший підхід: використання методу Comparator.comparing(). Цей метод автоматично обробляє логіку порівняння, роблячи її більш читабельною та лаконічною.
Потрібно лише передати посилання на метод, який витягує поле для порівняння.
Comparator.comparing(Book::getTitle)
Метод sort() списку викликає переданий Comparator, який, у свою чергу, визначає порядок елементів шляхом порівняння їх за значеннями, що повертаються вказаними методами.
Багаторівневе сортування
Якщо потрібно сортувати за декількома критеріями, можна використати метод thenComparing:
books.sort(
Comparator.comparing(Book::getYear) // First by year
.thenComparing(Book::getTitle) // Then by title
);
Цей приклад демонструє, як сортувати список книг спочатку за роком їхнього випуску (year), а потім за title. Процес сортування спочатку порівнює книги за полем year, і якщо у двох книг однаковий year, тоді вони порівнюються за title для визначення остаткового порядку.
Зворотне сортування
Зміна порядку сортування в Java корисна, коли потрібно сортувати елементи спочатку за одним критерієм, а потім змінити порядок для наступного критерію.
Методи reversed() та Comparator.reverseOrder() допомагають керувати напрямком сортування, але працюють по-різному.
books.sort(
Comparator.comparing(Book::getYear).reversed() // Sort by year (descending)
.thenComparing(Book::getTitle, Comparator.reverseOrder()) // Then by title (descending)
);
Книги спочатку сортуються за роком випуску у спадному порядку за допомогою reversed(). Якщо декілька книг мають однаковий year, метод thenComparing() сортує їх за title у зворотному алфавітному порядку з використанням Comparator.reverseOrder().
Це гарантує, що найновіші книги відображаються першими, а в межах одного року назви впорядковуються від Z до A.
Відмінності між Comparable та Comparator
Використовуйте інтерфейс Comparable, якщо клас має природний порядок сортування, наприклад, сортування за одним полем. Використовуйте Comparator, коли потрібно сортувати за декількома критеріями або визначити кастомний порядок для об'єктів.
1. Коли слід використовувати інтерфейс Comparable?
2. Коли слід використовувати інтерфейс Comparator?
Дякуємо за ваш відгук!