Menu
Coddy logo textTech

Interfejs Comparator

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

Chociaż interfejs Comparable definiuje naturalny porządek sortowania klasy, czasami trzeba sortować obiekty na różne sposoby. Interfejs Comparator pozwala tworzyć osobną logikę porównywania bez modyfikowania oryginalnej klasy.

Comparator to zewnętrzny obiekt, który porównuje dwa obiekty tego samego typu. Jest przydatny, gdy chcesz mieć wiele opcji sortowania lub gdy nie możesz zmodyfikować samej klasy:

import java.util.Comparator;

class NameComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getName().compareTo(p2.getName());
    }
}

class AgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
}

Możesz następnie przekazać komparator metodom sortującym:

List<Person> people = new ArrayList<>();
people.add(new Person("Charlie", 30));
people.add(new Person("Alice", 25));

Collections.sort(people, new NameComparator());  // Posortowane według imienia
Collections.sort(people, new AgeComparator());   // Posortowane według wieku

Aby uzyskać zwięzły kod, możesz używać wyrażeń lambda, ponieważ Comparator jest interfejsem funkcyjnym:

Collections.sort(people, (p1, p2) -> p1.getName().compareTo(p2.getName()));

Kluczowa różnica: klasa, której obiekty są porównywane, implementuje Comparable i definiuje jeden naturalny porządek, podczas gdy Comparator jest osobną klasą, która może definiować nieograniczoną liczbę niestandardowych porządków.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system sortowania pracowników, który pokazuje możliwości interfejsu Comparator. Utworzysz wiele komparatorów, aby sortować pracowników na różne sposoby — według wynagrodzenia i nazwiska — bez modyfikowania samej klasy Employee.

Rozmieścisz swój kod w czterech plikach:

  • Employee.java: Utwórz klasę reprezentującą pracownika z trzema prywatnymi polami: name (String), department (String) i salary (double). Dodaj konstruktor inicjalizujący wszystkie pola oraz metody pobierające wartość każdego z nich. Nadpisz toString(), aby zwracała: [name] ([department]) - $[salary]
  • SalaryComparator.java: Utwórz komparator sortujący pracowników według wynagrodzenia w kolejności malejącej (od najwyższego wynagrodzenia). Zaimplementuj interfejs Comparator<Employee> i jego metodę compare(). Użyj Double.compare(), aby bezpiecznie porównać wartości wynagrodzeń.
  • NameComparator.java: Utwórz kolejny komparator sortujący pracowników alfabetycznie według nazwiska w kolejności rosnącej (od A do Z). Zaimplementuj Comparator<Employee> i użyj metody compareTo() typu String do porównania.
  • Main.java: Połącz wszystkie elementy, tworząc listę pracowników i sortując ją za pomocą swoich komparatorów. Otrzymasz dane wejściowe trzech pracowników, każdy w osobnym wierszu w formacie: name,department,salary

    Utwórz ArrayList pracowników, a następnie zaprezentuj oba sposoby sortowania:

    1. Najpierw posortuj pracowników według wynagrodzenia za pomocą SalaryComparator i wyświetl każdego pracownika
    2. Wyświetl pusty wiersz
    3. Następnie posortuj pracowników według nazwiska za pomocą NameComparator i wyświetl każdego pracownika

Otrzymasz trzy wiersze danych wejściowych, każdy zawierający dane pracownika w formacie: name,department,salary

Na przykład wiersz danych wejściowych może wyglądać tak: Alice,Engineering,75000.0

Pamiętaj, aby zaimportować java.util.Comparator w plikach komparatorów oraz java.util.ArrayList, java.util.Collections i java.util.Scanner w pliku Main. Zwróć uwagę, że komparatory pozwalają definiować różne strategie sortowania na zewnątrz: klasa Employee nie musi wiedzieć nic o tym, jak można ją sortować!

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 dane trzech pracowników z wejścia
        // Format każdej linii: name,department,salary
        String line1 = scanner.nextLine();
        String line2 = scanner.nextLine();
        String line3 = scanner.nextLine();
        
        // TODO: Przetwórz każdą linię i utwórz obiekty Employee
        // Wskazówka: Użyj split(",") do rozdzielenia wartości
        
        // TODO: Utwórz ArrayList pracowników i dodaj do niej wszystkich trzech
        
        // TODO: Posortuj według wynagrodzenia za pomocą SalaryComparator i wypisz każdego pracownika
        // Wskazówka: Użyj Collections.sort(list, comparator)
        
        // TODO: Wypisz pustą linię
        
        // TODO: Posortuj według imienia za pomocą NameComparator i wypisz każdego pracownika
    }
}
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