Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте Компаратор: Користувацьке Порівняння Даних | Секція
Stream API в Java

bookКомпаратор: Користувацьке Порівняння Даних

Свайпніть щоб показати меню

Розглянемо другу функціональну інтерфейсну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

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
package 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?

question mark

Коли слід використовувати інтерфейс Comparable?

Select the correct answer

question mark

Коли слід використовувати інтерфейс Comparator?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 1. Розділ 9

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Секція 1. Розділ 9
some-alt