programowanieProgramista Backendowy

Opisz różnice między interfejsem Comparable a Comparator w Javie. Jak poprawnie je zaimplementować i stosować do sortowania obiektów użytkownika?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź

Comparable — to interfejs, który jest implementowany przez samą klasę obiektu. Określa jedną metodę compareTo(), która definiuje naturalny porządek sortowania.

Comparator — osobny interfejs, który implementuje metodę compare(o1, o2). Pozwala na definiowanie kilku sposobów sortowania bez zmiany kodu samej klasy.

Kiedy używać:

  • Jeśli klasa ma tylko jeden naturalny sposób sortowania — zaimplementuj Comparable.
  • Jeśli potrzebne jest wsparcie dla kilku sposobów sortowania — stwórz odpowiednie Comparator.

Przykłady:

// Comparable class Student implements Comparable<Student> { String name; int grade; public int compareTo(Student other) { return this.grade - other.grade; } } // Comparator Comparator<Student> byName = new Comparator<Student>() { public int compare(Student s1, Student s2) { return s1.name.compareTo(s2.name); } }; List<Student> students = ...; Collections.sort(students); // sortowanie według grade Collections.sort(students, byName); // sortowanie według name

Pytanie z pułapką

Czy można sortować List obiektów, które nie implementują Comparable, bez Comparator?

Odpowiedź: Nie. Jeśli klasa nie implementuje Comparable i nie przekazano wyraźnie Comparator, próba posortowania kolekcji spowoduje wyjątek ClassCastException.

Przykład:

class Animal {} List<Animal> animals = ...; Collections.sort(animals); // ClassCastException, jeśli nie ma Comparable

Historia

W projekcie inwentaryzacyjnym zapomniano zaimplementować Comparable dla klasy Item. Próba sortowania za pomocą Collections.sort(items) spowodowała, że aplikacja regularnie się zawieszała z powodu ClassCastException z powodu braku metody compareTo().


Historia

W serwisie obliczania rankingów uczniów programista zaimplementował porównanie według pola grade tylko w metodzie compareTo(). Później pojawiła się potrzeba sortowania według imienia i daty urodzenia, ale kod klasy uległ rozrostowi z powodu pomocniczych metod, zamiast użyć różnych Comparator i uniknąć złożonej logiki w compareTo().


Historia

W produkcie do zamówień online próbowano użyć Comparator z wyrażeniem lambda do sortowania zamówień według daty, jednak zapomniano uwzględnić możliwość wartości null dla daty. Efekt — niespodziewane NullPointerException w produkcji przy sortowaniu zamówień bez daty dostawy.