Sortuj listę tablicową obiektów niestandardowych według właściwości

Czytałem o sortowaniu ArrayLists za pomocą komparatora, ale we wszystkich przykładach ludzie używali compareTo, który według niektórych badań jest metodą dla Stringów.

Chciałem posortować ArrayList niestandardowych obiektów według jednej z ich właściwości: obiektu Date (getStartDay()). Normalnie porównuję je przez item1.getStartDate().before(item2.getStartDate()) więc zastanawiałem się czy mogę napisać coś w stylu:

public class CustomComparator {
    public boolean compare(Object object1, Object object2) {
        return object1.getStartDate().before(object2.getStartDate());
    }
}

public class RandomName {
    ...
    Collections.sort(Database.arrayList, new CustomComparator);
    ...
}
Rozwiązanie

Ponieważ Date implementuje Comparable, posiada metodę compareTo tak samo jak String.

Więc twój niestandardowy Comparator może wyglądać tak:

public class CustomComparator implements Comparator {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
}

Metoda compare() musi zwracać int, więc nie mogłeś'bezpośrednio zwracać boolean tak jak planowałeś.

Twój kod sortujący byłby mniej więcej taki, jak napisałeś:

Collections.sort(Database.arrayList, new CustomComparator());

Nieco krótszym sposobem na napisanie tego wszystkiego, jeśli nie musisz ponownie używać komparatora, jest napisanie go jako anonimowej klasy inline:

Collections.sort(Database.arrayList, new Comparator() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        return o1.getStartDate().compareTo(o2.getStartDate());
    }
});

Since [tag:java-8]

Możesz teraz napisać ostatni przykład w krótszej formie, używając wyrażenia lambda dla Komparatora:

Collections.sort(Database.arrayList, 
                        (o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

A List ma metodę sort(Comparator), więc możesz to jeszcze bardziej skrócić:

Database.arrayList.sort((o1, o2) -> o1.getStartDate().compareTo(o2.getStartDate()));

Jest to tak powszechny idiom, że istnieje wbudowana metoda do generowania Komparatora dla klasy z kluczem Comparable:

Database.arrayList.sort(Comparator.comparing(MyObject::getStartDate));

Wszystkie te formy są równoważne.

Komentarze (12)

Tak, możesz. Istnieją dwie opcje porównywania elementów, interfejs Comparable oraz interfejs Comparator.

Oba te interfejsy pozwalają na różne zachowania. Comparable pozwala na to, aby obiekt zachowywał się tak, jak właśnie opisałeś Strings (w rzeczywistości String implementuje Comparable). Drugi, Comparator, pozwala ci zrobić to, o co prosisz. Zrobiłbyś to w ten sposób:

Collections.sort(myArrayList, new MyComparator());

Spowoduje to, że metoda Collections.sort użyje twojego komparatora do swojego mechanizmu sortowania. Jeśli obiekty w ArrayList implementują porównywalność, możesz zamiast tego zrobić coś takiego:

Collections.sort(myArrayList);

Klasa Collections zawiera wiele takich użytecznych, popularnych narzędzi.

Komentarze (0)

Twoja klasa CustomComparator musi implementować java.util.Comparator, aby mogła być użyta. musi ona również nadpisać compare() AND equals()

compare() musi odpowiedzieć na pytanie: Czy obiekt 1 jest mniejszy, równy lub większy od obiektu 2?

pełna dokumentacja: http://java.sun.com/j2se/1.5.0/docs/api/java/util/Comparator.html

Komentarze (0)