compareTo() и Comparable
Часть раздела Объектно-ориентированное программирование путешествия по Java на Coddy. Урок 44 из 87.
Интерфейс Comparable позволяет объектам определять свой естественный порядок. Реализовав этот интерфейс, ваш class можно автоматически сортировать с помощью таких методов, как 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 Integer.compare(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);. Такой подход безопаснее и корректно обрабатывает крайние случаи. Для полей int предпочитайте Integer.compare(a, b) вместо a - b, поскольку при экстремальных значениях вычитание может привести к переполнению.
Задание
ЛегкоДавайте создадим систему рейтинга фильмов, которая использует интерфейс Comparable для сортировки фильмов по их рейтингам. Вы создадите Movie class, который умеет сравнивать себя с другими фильмами, обеспечивая автоматическую сортировку от самого высокого рейтинга к самому низкому.
Вы организуете код в двух файлах:
Movie.java: Create class, представляющий фильм, который можно сравнивать с другими фильмами. У Movie есть три private fields:title(String),director(String) иrating(double, от 0.0 до 10.0). Включите constructor для инициализации всех fields и методы Getter для каждого из них.Сделайте так, чтобы ваш Movie class implement
Comparable<Movie>, и переопределите методcompareTo(). Фильмы должны сортироваться по рейтингу в descending order (сначала с самым высоким рейтингом). При сравнении значений double используйтеDouble.compare()для безопасного сравнения: помните, что для descending сортировки нужно изменить порядок!Переопределите
toString(), чтобы он возвращал:[title] by [director] - Rating: [rating]Main.java: Воплотите свой Movie class в жизнь, создав list фильмов и отсортировав их. Вы получите ввод для трёх фильмов, каждый в отдельной строке, в формате:title,director,ratingРазберите каждую строку, чтобы создать объекты Movie, добавьте их в
ArrayList, затем используйтеCollections.sort(), чтобы отсортировать list. Благодаря вашей реализацииComparableфильмы автоматически расположатся по рейтингу!После сортировки выведите каждый фильм в отдельной строке, используя формат
toString(). Фильм с самым высоким рейтингом должен находиться первым.
Вы получите три строки ввода, каждая из которых содержит данные о фильме в формате: title,director,rating
Например, строка ввода может выглядеть так: Inception,Christopher Nolan,8.8
Не забудьте импортировать java.util.ArrayList, java.util.Collections и java.util.Scanner в ваш файл Main. Обратите внимание, как реализация Comparable позволяет сортировать ваши пользовательские объекты одним вызовом метода: дополнительный компаратор не нужен!
Попробуйте сами
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: Разобрать каждую строку (формат: title,director,rating)
// Hint: Используйте split(",") для разделения частей
// Hint: Используйте 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
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»Паттерн «Итератор»Потренируйтесь самостоятельно: Онлайн-компилятор Java