Menu
Coddy logo textTech

compareTo() i Comparable

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 44 z 87.

Interfejs Comparable pozwala obiektom definiować ich naturalny porządek. Implementując ten interfejs, możesz automatycznie sortować swoją klasę za pomocą metod takich jak Collections.sort() lub przechowywać jej obiekty w posortowanych kolekcjach, takich jak TreeSet.

Interfejs wymaga zaimplementowania jednej metody: compareTo(). Ta metoda porównuje bieżący obiekt z innym obiektem i zwraca liczbę całkowitą wskazującą ich kolejność względem siebie:

  • Wartość ujemna: ten obiekt jest przed drugim
  • Zero: oba obiekty są równe
  • Wartość dodatnia: ten obiekt jest po drugim
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);  // Sortuj według wieku rosnąco
    }
}

Po zaimplementowaniu sortowanie staje się proste:

List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 30));
people.add(new Person("Bob", 25));
Collections.sort(people);  // Teraz posortowane według wieku: Bob, Alice

Do porównywania ciągów znaków lub innych pól implementujących Comparable możesz delegować porównanie do ich metody compareTo() zamiast używać odejmowania: return this.name.compareTo(other.name);. To podejście jest bezpieczniejsze i prawidłowo obsługuje przypadki brzegowe. W przypadku pól typu int preferuj Integer.compare(a, b) zamiast a - b, ponieważ odejmowanie może powodować przepełnienie dla skrajnych wartości.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system rankingu filmów, który używa interfejsu Comparable do sortowania filmów według ocen. Utworzysz klasę Movie, która potrafi porównywać się z innymi filmami, umożliwiając automatyczne sortowanie od najwyżej do najniżej ocenianych.

Rozmieścisz swój kod w dwóch plikach:

  • Movie.java: Utwórz klasę reprezentującą film, który można porównywać z innymi filmami. Film ma trzy pola prywatne: title (String), director (String) i rating (double, od 0.0 do 10.0). Dodaj konstruktor inicjalizujący wszystkie pola oraz metody pobierające wartości każdego z nich.

    Zaimplementuj w klasie Movie interfejs Comparable<Movie> i nadpisz metodę compareTo(). Filmy powinny być sortowane według oceny w kolejności malejącej (najwyżej oceniany film jako pierwszy). Przy porównywaniu wartości typu double użyj Double.compare(), aby bezpiecznie je porównać: pamiętaj, aby odwrócić kolejność przy sortowaniu malejącym!

    Nadpisz toString(), aby zwracała: [title] by [director] - Rating: [rating]

  • Main.java: Ożyw swoją klasę Movie, tworząc listę filmów i sortując ją. Otrzymasz dane wejściowe dla trzech filmów, każdy w osobnym wierszu, w formacie: title,director,rating

    Przetwórz każdy wiersz, aby utworzyć obiekty Movie, dodaj je do ArrayList, a następnie użyj Collections.sort(), aby posortować listę. Dzięki implementacji interfejsu Comparable filmy automatycznie ustawią się według oceny!

    Po sortowaniu wypisz każdy film w osobnym wierszu, używając formatu toString(). Najwyżej oceniany film powinien pojawić się jako pierwszy.

Otrzymasz trzy wiersze danych wejściowych, każdy zawierający dane filmu w formacie: title,director,rating

Przykładowy wiersz danych wejściowych może wyglądać tak: Inception,Christopher Nolan,8.8

Pamiętaj, aby zaimportować java.util.ArrayList, java.util.Collections i java.util.Scanner w pliku Main. Zauważ, że implementacja interfejsu Comparable pozwala sortować własne obiekty za pomocą jednego wywołania metody: nie potrzebujesz dodatkowego komparatora!

Spróbuj swoich sił

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);
        
        // Wczytaj trzy wiersze danych o filmach
        String line1 = scanner.nextLine();
        String line2 = scanner.nextLine();
        String line3 = scanner.nextLine();
        
        // TODO: Utwórz ArrayList do przechowywania obiektów Movie
        
        // TODO: Przetwórz każdy wiersz (format: title,director,rating)
        // Wskazówka: Użyj split(",") do rozdzielenia części
        // Wskazówka: Użyj Double.parseDouble() do przetworzenia oceny
        
        // TODO: Utwórz obiekty Movie i dodaj je do listy
        
        // TODO: Posortuj listę za pomocą Collections.sort()
        
        // TODO: Wypisz każdy film (po jednym w wierszu)
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online