Comparator i sortowanie za pomocą lambd
Twórz obiekty Comparator za pomocą wyrażeń lambda i fabrycznych metod Comparator.comparing.
Comparator i sortowanie za pomocą lambd to bezpłatna lekcja Java Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Java Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Java Academy zawiera 4 lekcji w sumie.
Comparator i sortowanie za pomocą lambd
Comparator<T> definiuje zewnętrzny porządek obiektów. W przeciwieństwie do Comparable można utworzyć dowolną liczbę komparatorów bez modyfikowania klasy.
Tworzenie komparatorów
Komparator można utworzyć za pomocą lambdy lub odwołania do metody, a następnie przekazać go do metod sortujących.
import java.util.*;
record Product(String name, double price, int stock) {}
List<Product> products = new ArrayList<>(List.of(
new Product("Mouse", 29.99, 50),
new Product("Laptop", 999.00, 5),
new Product("USB Hub", 24.99, 100)
));
// Lambda comparator
products.sort((a, b) -> Double.compare(a.price(), b.price()));
System.out.println(products);
// [USB Hub, Mouse, Laptop] (by price ascending)Fabryka Comparator.comparing
Comparator.comparing(keyExtractor) tworzy Comparator na podstawie funkcji ekstrakcji klucza — jest to czytelniejsze niż używanie surowych lambd.
import java.util.Comparator;
Comparator<Product> byPrice = Comparator.comparingDouble(Product::price);
Comparator<Product> byName = Comparator.comparing(Product::name);
Comparator<Product> byStock = Comparator.comparingInt(Product::stock);
products.sort(byPrice);
System.out.println(products); // sorted by price ascending
products.sort(byName);
System.out.println(products); // sorted alphabeticallyreversed()
reversed() odwraca porządek dowolnego komparatora.
import java.util.Comparator;
Comparator<Product> mostExpensiveFirst =
Comparator.comparingDouble(Product::price).reversed();
products.sort(mostExpensiveFirst);
System.out.println(products);
// [Laptop($999.0), Mouse($29.99), USB Hub($24.99)]naturalOrder i reverseOrder
Comparator.naturalOrder() używa Comparable danej klasy. reverseOrder() odwraca ten porządek.
List<String> names = new ArrayList<>(List.of("Charlie", "Alice", "Bob"));
names.sort(Comparator.naturalOrder());
System.out.println(names); // [Alice, Bob, Charlie]
names.sort(Comparator.reverseOrder());
System.out.println(names); // [Charlie, Bob, Alice]
// Sort integers descending
List<Integer> nums = new ArrayList<>(List.of(5, 2, 8, 1, 9));
nums.sort(Comparator.reverseOrder());
System.out.println(nums); // [9, 8, 5, 2, 1]Komparatory bezpieczne dla wartości null
Comparator.nullsFirst() i nullsLast() obsługują elementy null bez powodowania NPE.
import java.util.*;
List<String> withNulls = new ArrayList<>(Arrays.asList("Charlie", null, "Alice", null, "Bob"));
withNulls.sort(Comparator.nullsLast(Comparator.naturalOrder()));
System.out.println(withNulls); // [Alice, Bob, Charlie, null, null]
withNulls.sort(Comparator.nullsFirst(Comparator.naturalOrder()));
System.out.println(withNulls); // [null, null, Alice, Bob, Charlie]sorted() w Stream z Comparator
Należy użyć pośredniej operacji strumienia sorted() wraz z Comparator do sortowania w stylu funkcyjnym.
import java.util.stream.*;
record Employee(String name, String dept, double salary) {}
List<Employee> employees = List.of(
new Employee("Alice", "Engineering", 95000),
new Employee("Bob", "Marketing", 72000),
new Employee("Charlie", "Engineering", 105000)
);
// Sort by salary descending in a stream pipeline
employees.stream()
.sorted(Comparator.comparingDouble(Employee::salary).reversed())
.forEach(e -> System.out.println(e.name() + ": $" + e.salary()));
// Charlie: $105000.0 / Alice: $95000.0 / Bob: $72000.0Comparator jako lambda a odwołanie do metody
Odwołania do metod pozwalają jeszcze bardziej skrócić komparatory, gdy funkcja ekstrakcji klucza jest prostym getterem.
// Lambda
Comparator<String> c1 = (a, b) -> a.length() - b.length();
// Comparator.comparing with lambda
Comparator<String> c2 = Comparator.comparing(s -> s.length());
// Comparator.comparingInt with method reference (cleanest)
Comparator<String> c3 = Comparator.comparingInt(String::length);
List<String> words = new ArrayList<>(List.of("banana", "fig", "apple", "kiwi"));
words.sort(c3);
System.out.println(words); // [fig, kiwi, apple, banana]Komparator ze stanem
Chociaż komparatory powinny zwykle być bezstanowe, można przekazywać im konfigurację za pomocą parametrów konstruktora.
class DistanceComparator implements Comparator<String> {
private final String target;
DistanceComparator(String target) { this.target = target; }
@Override
public int compare(String a, String b) {
return Integer.compare(distance(a), distance(b));
}
private int distance(String s) { return Math.abs(s.length() - target.length()); }
}
List<String> words = new ArrayList<>(List.of("Java", "Go", "Python", "C", "Kotlin"));
words.sort(new DistanceComparator("Java"));
System.out.println(words); // closest length to "Java" firstNiestandardowe sortowanie katalogu produktów
Sortowanie katalogu produktów najpierw według dostępności, następnie ceny, a na końcu nazwy.
import java.util.*;
record Item(String name, double price, boolean inStock) {}
List<Item> catalog = List.of(
new Item("Laptop", 999.0, true),
new Item("Case", 19.99, false),
new Item("Mouse", 29.99, true),
new Item("Monitor", 349.0, true)
);
Comparator<Item> catalogSort =
Comparator.comparing(Item::inStock).reversed() // in-stock first
.thenComparingDouble(Item::price) // then cheapest
.thenComparing(Item::name); // then alphabetical
catalog.stream().sorted(catalogSort)
.forEach(i -> System.out.printf("%s %-15s $%.2f%n",
i.inStock() ? "[Y]" : "[N]", i.name(), i.price()));Arrays.sort z Comparator
Arrays.sort(array, comparator) sortuje tablice obiektów za pomocą niestandardowego komparatora.
String[] words = {"banana", "fig", "apple", "kiwi", "cherry"};
// Sort by length, then alphabetically for same length
Arrays.sort(words,
Comparator.comparingInt(String::length)
.thenComparing(Comparator.naturalOrder()));
System.out.println(Arrays.toString(words));
// [fig, kiwi, apple, banana, cherry]Szybkie sprawdzenie
Co zwraca Comparator.comparingDouble(Product::price).reversed()?
Podsumowanie: Comparator i sortowanie za pomocą lambd
Najważniejsze informacje:
- Comparator<T> definiuje zewnętrzny porządek — można używać dowolnej liczby komparatorów
- Comparator.comparing(keyExtractor) tworzy komparatory na podstawie getterów
- reversed() odwraca dowolny komparator; naturalOrder()/reverseOrder() służą do typów implementujących Comparable
- nullsFirst() i nullsLast() bezpiecznie obsługują elementy null
- W potokach Stream należy używać sorted(comparator) do porządkowania w stylu funkcyjnym
- Komparatory można przekazywać do sort(), Arrays.sort(), TreeSet i TreeMap
Często zadawane pytania
Czy lekcja „Comparator i sortowanie za pomocą lambd” jest bezpłatna?
Tak — pełny tekst „Comparator i sortowanie za pomocą lambd” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Java Academy, przejdź na CoddyKit PRO. Kurs Java Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Comparator i sortowanie za pomocą lambd”?
Twórz obiekty Comparator za pomocą wyrażeń lambda i fabrycznych metod Comparator.comparing. Ćwiczysz Java Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Java Academy?
Nie wymagamy żadnego doświadczenia. Java Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.
Ile czasu zajmuje lekcja „Comparator i sortowanie za pomocą lambd”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Java Academy?
Tak. Każda lekcja Java Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Interfejs Comparable
- Comparator i sortowanie za pomocą lambd
- Sortowanie według wielu kluczy za pomocą thenComparing
- Sortowanie tablic i kolekcji w praktyce