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 wiekuAby 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.
Wyzwanie
ŁatwyZbudujmy 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) isalary(double). Dodaj konstruktor inicjalizujący wszystkie pola oraz metody pobierające wartość każdego z nich. NadpisztoString(), 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 interfejsComparator<Employee>i jego metodęcompare(). UżyjDouble.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). ZaimplementujComparator<Employee>i użyj metodycompareTo()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,salaryUtwórz
ArrayListpracowników, a następnie zaprezentuj oba sposoby sortowania:- Najpierw posortuj pracowników według wynagrodzenia za pomocą
SalaryComparatori wyświetl każdego pracownika - Wyświetl pusty wiersz
- Następnie posortuj pracowników według nazwiska za pomocą
NameComparatori wyświetl każdego pracownika
- Najpierw posortuj pracowników według wynagrodzenia za pomocą
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
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe thisMetodyPola (atrybuty)Metoda konstruktoraPrzeciążanie konstruktoraPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawy dziedziczenia (extends)Słowo kluczowe superPrzesłanianie metod (@Override)Łańcuch wywołań konstruktorówKlasa ObjectDziedziczenie jedno- i wielopoziomoweDlaczego Java nie obsługuje wielodziedziczenia klasPodsumowanie – hierarchia pracowników7Metody specjalne i klasa Object
Metoda toString()equals() i hashCode()Metoda clone()compareTo() i ComparableInterfejs ComparatorPodsumowanie — własne sortowanie10Obsługa wyjątków w programowaniu obiektowym
Hierarchia klas wyjątkówWłasne wyjątkiBłędy sprawdzane a niesprawdzaneWzorzec try-with-resourcesPodsumowanie – zweryfikowany użytkownik2Modyfikatory dostępu i enkapsulacja
Przegląd poziomów dostępuMetody pobierające i ustawiająceUkrywanie informacjiSłowo kluczowe finalPodsumowanie — menedżer kont bankowych5Polimorfizm
Podstawy przeciążania metodPrzesłanianie metod (w czasie wykonywania)Rzutowanie w górę i w dółOperator instanceofKlasy i metody abstrakcyjnePowtórka — kalkulator figur8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieAgregacja a kompozycjaKlasy wewnętrzne, zagnieżdżone i anonimoweEnumy i metody enumówRekordy (Java 16+)Klasy zapieczętowane (Java 17+)11Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec BuilderWzorzec ObserverWzorzec Strategy3Właściwości klas i składowe statyczne
Zmienne instancji a zmienne statyczneMetody statyczneBloki statyczneStałe (static final)Powtórka – Counter i Utility6Interfejsy i klasy abstrakcyjne
Wprowadzenie do interfejsówImplementowanie interfejsówImplementacja wielu interfejsówMetody domyślne i statyczne w interfejsieKlasy abstrakcyjne a interfejsyInterfejsy funkcyjnePodsumowanie — system płatnościPoćwicz samodzielnie: Kompilator Java online