Menu
Coddy logo textTech

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

challenge icon

Задание

Легко

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

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

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

Потренируйтесь самостоятельно: Онлайн-компилятор Java