compareTo() и Comparable
Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy — урок 44 из 87.
Интерфейс Comparable позволяет объектам определять их естественный порядок. Реализовав этот интерфейс, ваш класс сможет автоматически сортироваться с помощью таких методов, как Collections.sort(), или храниться в отсортированных коллекциях, таких как TreeSet.
Интерфейс требует от вас реализации одного метода: compareTo(). Этот метод сравнивает текущий объект с другим объектом и возвращает целое число, указывающее на их относительный порядок:
- Отрицательное значение: этот объект идет перед другим
- Ноль: оба объекта равны
- Положительное значение: этот объект идет после другого
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person other) {
return this.age - other.age; // Сортировка по возрасту по возрастанию
}
}После реализации сортировка становится простой:
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people); // Теперь отсортировано по возрасту: Bob, AliceДля сравнения строк или других Comparable полей вы можете делегировать выполнение их методу compareTo() вместо использования вычитания: return this.name.compareTo(other.name);. Этот подход более безопасен и правильно обрабатывает граничные случаи.
Задание
ЛегкоДавайте создадим систему рейтинга фильмов, которая использует интерфейс Comparable для сортировки фильмов по их рейтингу. Вы создадите класс Movie, который умеет сравнивать себя с другими фильмами, что позволит выполнять автоматическую сортировку от самого высокого рейтинга к самому низкому.
Вы организуете свой код в двух файлах:
Movie.java: Создайте класс, представляющий фильм, который можно сравнивать с другими фильмами. У Movie есть три приватных поля:title(String),director(String) иrating(double, от 0.0 до 10.0). Включите конструктор для инициализации всех полей и методы-геттеры для каждого из них.Сделайте так, чтобы ваш класс Movie реализовывал интерфейс
Comparable<Movie>и переопределял методcompareTo(). Фильмы должны быть отсортированы по рейтингу в descending order (сначала с самым высоким рейтингом). При сравнении чисел типа double используйтеDouble.compare()для безопасного сравнения — не забудьте изменить порядок для сортировки по убыванию!Переопределите
toString(), чтобы он возвращал:[title] by [director] - Rating: [rating]Main.java: Оживите свой класс Movie, создав список фильмов и отсортировав их. Вы получите входные данные для трех фильмов, каждый на отдельной строке в формате:title,director,ratingРазберите каждую строку для создания объектов Movie, добавьте их в
ArrayList, а затем используйтеCollections.sort()для сортировки списка. Благодаря вашей реализацииComparable, фильмы автоматически выстроятся по рейтингу!После сортировки выведите каждый фильм на отдельной строке, используя формат
toString(). Фильм с самым высоким рейтингом должен идти первым.
Вы получите три строки входных данных, каждая из которых содержит данные о фильме в формате: title,director,rating
Например, входная строка может выглядеть так: Inception,Christopher Nolan,8.8
Не забудьте импортировать java.util.ArrayList, java.util.Collections и java.util.Scanner в вашем файле Main. Обратите внимание, как реализация Comparable позволяет сортировать ваши пользовательские объекты одним вызовом метода — никакой дополнительный компаратор не требуется!
Шпаргалка
Интерфейс Comparable позволяет объектам определять их естественный порядок для автоматической сортировки.
Реализуйте метод compareTo(), который возвращает:
- Отрицательное значение: этот объект идет перед другим
- Ноль: оба объекта равны
- Положительное значение: этот объект идет после другого
public class Person implements Comparable<Person> {
private int age;
@Override
public int compareTo(Person other) {
return this.age - other.age; // Sort by age ascending
}
}Сортируйте объекты с помощью Collections.sort():
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people); // Sorted by ageДля сравнения строк делегируйте выполнение их методу compareTo():
return this.name.compareTo(other.name);Для безопасного сравнения чисел типа double используйте Double.compare():
return Double.compare(this.rating, other.rating); // Ascending
return Double.compare(other.rating, this.rating); // DescendingПопробуйте сами
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Прочитать три строки данных о фильмах
String line1 = scanner.nextLine();
String line2 = scanner.nextLine();
String line3 = scanner.nextLine();
// TODO: Создать ArrayList для хранения объектов Movie
// TODO: Разобрать каждую строку (формат: название,режиссер,рейтинг)
// Подсказка: Используйте split(",") для разделения частей
// Подсказка: Используйте Double.parseDouble() для рейтинга
// TODO: Создать объекты Movie и добавить их в список
// TODO: Отсортировать список с помощью Collections.sort()
// TODO: Вывести каждый фильм (по одному на строку)
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово thisМетодыПоля (атрибуты)Метод-конструкторПерегрузка конструкторовИтоги — Простой калькулятор4Наследование
Основы наследования (extends)Ключевое слово superПереопределение методов (@Override)Цепочка конструкторовКласс ObjectОдиночное и многоуровневое наследованиеПочему нет множественного наследования классовИтоги — Иерархия сотрудников7Специальные методы и класс Object
Метод toString()equals() и hashCode()Метод clone()compareTo() и ComparableИнтерфейс ComparatorПовторение — Кастомная сортировка2Модификаторы доступа и инкапсуляция
Обзор уровней доступаМетоды геттеры и сеттерыСокрытие данныхКлючевое слово finalИтоги — Менеджер банковского счета5Полиморфизм
Основы перегрузки методовПереопределение методов (Run-Time)Upcasting и DowncastingОператор instanceofАбстрактные классы и методыИтоги: Калькулятор фигур8Продвинутые концепции ООП
Композиция против наследованияАгрегация против композицииВнутренние, вложенные и анонимные классыEnums и методы перечисленийRecords (Java 16+)Sealed-классы (Java 17+)11Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy3Свойства класса и статические члены
Переменные экземпляра и статические переменныеСтатические методыСтатические блокиКонстанты (static final)Итоги: Счетчик и утилиты6Интерфейсы и абстрактные классы
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовDefault и Static методы в интерфейсахАбстрактные классы vs ИнтерфейсыФункциональные интерфейсыИтоги — Платежная система9Обобщения
Введение в обобщенияОбобщенные классыОбобщенные методыОграниченные параметры типаСимволы подстановки (Wildcards: ?, extends, super)Итоги — Обобщенный контейнер12Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»