Menu
Coddy logo textTech

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 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, поскольку вычитание может привести к переполнению при экстремальных значениях.

challenge icon

Задание

Легко

Давайте создадим систему рейтинга фильмов, которая использует интерфейс 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 позволяет сортировать ваши пользовательские объекты одним вызовом метода — никакой дополнительный компаратор не требуется!

Попробуйте сами

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: Вывести каждый фильм (по одному на строку)
    }
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование