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 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);. Этот подход более безопасен и правильно обрабатывает граничные случаи.

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

Шпаргалка

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

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

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