Sortuj ArrayList niestandardowych obiektów według właściwości

1145

Czytałem o sortowaniu ArrayLists przy użyciu Komparatora, ale we wszystkich przykładach ludzie używali, compareToco według niektórych badań jest metodą dla Ciągów.

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

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);
    ...
}
Samuel
źródło
2
Odpowiedź @Yishai w tym poście pokazuje eleganckie zastosowanie wyliczenia do niestandardowego sortowania i grupowania (wiele argumentów) z wykorzystaniem łańcucha komparatorów.
gunalmel

Odpowiedzi:

1536

Ponieważ Dateimplementuje Comparable, ma taką compareTosamą metodę jak String.

Twój zwyczaj Comparatormoże wyglądać następująco:

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

compare()Metoda musi zwracać liczbę int, więc nie można bezpośrednio zwracają booleansię jak planowaliśmy tak.

Twój kod sortowania będzie mniej więcej taki, jak napisałeś:

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

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

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

Od

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

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

I Listma sort(Comparator)metodę, dzięki czemu możesz jeszcze bardziej ją skrócić:

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

Jest to tak powszechny idiom, że istnieje wbudowana metoda generowania Comparatorklasy dla Comparableklucza z kluczem:

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

Wszystkie są równoważnymi formami.

Michael Myers
źródło
33
+1 za wzmiankę, że powinien powrócić inti że lepiej do tego użyć Date#compareTo(). Dlaczego nie jest to wyżej oceniane, druga odpowiedź jest poza mną. Ten link może być także przydatny: Samouczek dotyczący zamawiania obiektów w Sun.com .
BalusC
5
Myślę, że najlepsza odpowiedź powinna również zawierać właściwy sposób zrobienia tego w Javie 8. Collections.sort (list, Comparator.comparing (MyObject :: getStartDate)); który czyta lepiej i jest mniej podatny na błędy. Bardzo łatwo jest napisać return o1.getStartDate (). CompareTo (o1.getStartDate ());
Kuba
2
Klasa komparatora powinna być statyczna :)
Jarmez De La Rocha
4
@ Kuba jeszcze lepiej, użyj List.sort().
shmosel
3
To rozwiązanie nie działa w systemie Android API <24. Czy znacie na to rozwiązanie?
Jim Clermonts
194

Klasy, które mają naturalny porządek sortowania (na przykład numer klasy) powinny implementować interfejs Porównywalny, podczas gdy klasy, które nie mają naturalnego porządku sortowania (na przykład Krzesło klasy), powinny być wyposażone w Komparator (lub anonimowy Komparator klasa).

Dwa przykłady:

public class Number implements Comparable<Number> {
    private int value;

    public Number(int value) { this.value = value; }
    public int compareTo(Number anotherInstance) {
        return this.value - anotherInstance.value;
    }
}

public class Chair {
    private int weight;
    private int height;

    public Chair(int weight, int height) {
        this.weight = weight;
        this.height = height;
    }
    /* Omitting getters and setters */
}
class ChairWeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getWeight() - chair2.getWeight();
    }
}
class ChairHeightComparator implements Comparator<Chair> {
    public int compare(Chair chair1, Chair chair2) {
        return chair1.getHeight() - chair2.getHeight();
    }
}

Stosowanie:

List<Number> numbers = new ArrayList<Number>();
...
Collections.sort(numbers);

List<Chair> chairs = new ArrayList<Chair>();
// Sort by weight:
Collections.sort(chairs, new ChairWeightComparator());
// Sort by height:
Collections.sort(chairs, new ChairHeightComparator());

// You can also create anonymous comparators;
// Sort by color:
Collections.sort(chairs, new Comparator<Chair>() {
    public int compare(Chair chair1, Chair chair2) {
        ...
    }
});
Björn
źródło
Próbowałem tego - ale kiedy chcę uzyskać dostęp do klasy porównawczej ChairWeightComparator na zewnątrz w innej klasie, nie uzyskuję dostępu do tej klasy (oczywiście nie, ponieważ nie jest ona publiczna). Czy muszę utworzyć nową publiczną klasę ChairWeightComparator w osobnym pliku? - czy naprawdę jestem pierwszym, który wypróbował to po 3 latach, czy może coś przeoczyłem?
user387184
@ user387184 - po prostu upublicznij i umieść w swoim własnym pliku (najlepiej również w swoim własnym pakiecie), a będziesz mógł używać go wszędzie w swoim projekcie. Nie ma potrzeby tworzenia dodatkowej klasy!
Björn
masz na myśli utworzenie nowego pliku - nie klasy i wstawienie kodu: „klasa ChairWeightComparator implementuje Komparator <Krzesło> {....”?
user387184
@ użytkownik387184, dokładnie - ale z kluczowym słowem publicprzed class.
Björn
157

Do sortowania ArrayListmożesz użyć następującego fragmentu kodu:

Collections.sort(studList, new Comparator<Student>(){
    public int compare(Student s1, Student s2) {
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
    }
});
czarna pantera
źródło
1
Każdy, kto używa lambda stackoverflow.com/questions/2784514/…
Sorter
To sortuje, ale daje podwójną wartość dla każdego elementu
Sam
44

Tak, możesz. Istnieją dwie opcje porównywania elementów, interfejs porównywalny i komparator interfejs .

Oba te interfejsy pozwalają na różne zachowanie. Porównywalny pozwala sprawić, aby obiekt działał tak, jak właśnie opisałeś Ciągi (w rzeczywistości String implementuje Porównywalny). Drugi, Komparator, pozwala ci robić to, o co prosisz. Zrobiłbyś to w ten sposób:

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

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

Collections.sort(myArrayList);

Kolekcje klasa zawiera szereg tych przydatnych, wspólnych narzędzi.

aperkins
źródło
42

JAVA 8 wyrażenie lambda

Collections.sort(studList, (Student s1, Student s2) ->{
        return s1.getFirstName().compareToIgnoreCase(s2.getFirstName());
});

LUB

Comparator<Student> c = (s1, s2) -> s1.firstName.compareTo(s2.firstName);
studList.sort(c)
Sorter
źródło
3
LubCollections.sort(studList, Comparator.comparing(Student::getFirstName));
Holger
5
.. lubstudList.sort(Comparator.comparing(Student::getFirstName));
Alexis C.,
W twoim przypadku kolejność sortowania zawsze będzie rosła. W moim przykładzie zadbałem też o porządek sortowania. Dzięki Panowie.
Sorter
33

W Javie 8 możesz użyć odwołania do metody dla swojego komparatora:

import static java.util.Comparator.comparing;

Collections.sort(list, comparing(MyObject::getStartDate));
assylias
źródło
@ user387184 niestety Android nie obsługuje Java 8, chociaż może istnieć obejście (nie testowałem tego).
assylias
14

Ponieważ technologie pojawiają się codziennie, odpowiedź zmieni się z czasem. Spojrzałem na LambdaJ i wydaje się bardzo interesujący.

Możesz spróbować rozwiązać te zadania za pomocą LambdaJ . Można go znaleźć tutaj: http://code.google.com/p/lambdaj/

Oto przykład:

Sortuj iteracyjnie

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
        public int compare(Person p1, Person p2) {
           return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
        }
});

Sortuj z lambda

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

Oczywiście, że tego rodzaju piękno wpływa na wydajność (średnio 2 razy), ale czy możesz znaleźć bardziej czytelny kod?

Federico Piazza
źródło
To sortuje, ale daje podwójną wartość dla każdego elementu, jak tego uniknąć
Sam
@Sam, nie powinno ... działa zgodnie z oczekiwaniami. Chyba że używasz nowej wersji z błędem, który polecam opublikować na forum. W każdym razie ta odpowiedź została opublikowana przed java 8, jeśli ją wykorzystasz, to będzie znacznie lepsza niż użycie lambdaj
Federico Piazza
Musiałem usunąć nawet elementy z pętli foreach, w przeciwnym razie daje mi to podwójną zawartość.
Sam
13
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;

public class test {

public static class Person {
    public String name;
    public int id;
    public Date hireDate;

    public Person(String iname, int iid, Date ihireDate) {
        name = iname;
        id = iid;
        hireDate = ihireDate;
    }

    public String toString() {
        return name + " " + id + " " + hireDate.toString();
    }

    // Comparator
    public static class CompId implements Comparator<Person> {
        @Override
        public int compare(Person arg0, Person arg1) {
            return arg0.id - arg1.id;
        }
    }

    public static class CompDate implements Comparator<Person> {
        private int mod = 1;
        public CompDate(boolean desc) {
            if (desc) mod =-1;
        }
        @Override
        public int compare(Person arg0, Person arg1) {
            return mod*arg0.hireDate.compareTo(arg1.hireDate);
        }
    }
}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    SimpleDateFormat df = new SimpleDateFormat("mm-dd-yyyy");
    ArrayList<Person> people;
    people = new ArrayList<Person>();
    try {
        people.add(new Person("Joe", 92422, df.parse("12-12-2010")));
        people.add(new Person("Joef", 24122, df.parse("1-12-2010")));
        people.add(new Person("Joee", 24922, df.parse("12-2-2010")));
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    Collections.sort(people, new Person.CompId());
    System.out.println("BY ID");
    for (Person p : people) {
        System.out.println(p.toString());
    }

    Collections.sort(people, new Person.CompDate(false));
    System.out.println("BY Date asc");
    for (Person p : people) {
        System.out.println(p.toString());
    }
    Collections.sort(people, new Person.CompDate(true));
    System.out.println("BY Date desc");
    for (Person p : people) {
        System.out.println(p.toString());
    }

}

}
CharlesW
źródło
7
Witamy w Stackoverflow. Na to pytanie odpowiedziano jakiś czas temu. Przed wskrzeszeniem starych wątków upewnij się, że twoja odpowiedź dodaje coś ważnego do wątku.
Leigh
1
Dodaj wyjaśnienie do swojej odpowiedzi.
Arashsoft,
Po prostu skompiluj i uruchom. Kod jest komentarzem i wyjaśnieniem.
CharlesW
9

Najlepszym łatwym sposobem z JAVA 8 jest sortowanie alfabetu angielskiego

Implementacja klasy

public class NewspaperClass implements Comparable<NewspaperClass>{
   public String name;

   @Override
   public int compareTo(NewspaperClass another) {
      return name.compareTo(another.name);
   }
}

Sortować

  Collections.sort(Your List);

Jeśli chcesz sortować według alfabetu zawierającego znaki inne niż angielskie, możesz użyć ustawień regionalnych ... Poniżej kodu użyj sortowania znaków tureckich ...

Implementacja klasy

public class NewspaperClass implements Comparator<NewspaperClass> {
   public String name;
   public Boolean isUserNewspaper=false;
   private Collator trCollator = Collator.getInstance(new Locale("tr_TR"));



   @Override
   public int compare(NewspaperClass lhs, NewspaperClass rhs) {
      trCollator.setStrength(Collator.PRIMARY);
      return trCollator.compare(lhs.name,rhs.name);
   }
}

Sortować

Collections.sort(your array list,new NewspaperClass());
Beyaz
źródło
9

Odniesienie do funkcji i metod

Collections.sortSposób można sortować Listza pomocą Comparatorprzekazać. Które Comparatormogą być realizowane przy użyciu Comparator.comparingmetody, gdzie można zdać Referencyjna metoda jako niezbędneFunction . Na szczęście rzeczywisty kod jest znacznie prostszy i krótszy niż ten opis.

W przypadku Java 8:

Collections.sort(list, comparing(ClassName::getName));

lub

Collections.sort(list, comparing(ClassName::getName).reversed());

Innym sposobem jest

Collections.sort(list, comparing(ClassName::getName, Comparator.nullsLast(Comparator.naturalOrder())));
Bieg
źródło
1
Połączenie wymaga interfejsu API na poziomie 24
akshay bhange
6

Java 8 Lambda skraca sort.

Collections.sort(stdList, (o1, o2) -> o1.getName().compareTo(o2.getName()));
javasenior
źródło
2
Collections.sort(stdList, Comparator.comparing(SomeClass::getName));
bcsb1001
5

Tak, jest to możliwe na przykład w tej odpowiedzi sortuję według właściwości vklasyIndexValue

    // Sorting by property v using a custom comparator.
    Arrays.sort( array, new Comparator<IndexValue>(){
        public int compare( IndexValue a, IndexValue b ){
            return a.v - b.v;
        }
    });

Jeśli zauważysz tutaj, tworzę anonimową klasę wewnętrzną (która jest Javą dla zamknięć) i przekazuję ją bezpośrednio do sortmetody klasyArrays

Twój obiekt może również zaimplementować Comparable(tak właśnie robi String i większość bibliotek podstawowych w Javie), ale to zdefiniowałoby „naturalną kolejność sortowania” klasy, którą on sam, i nie pozwala na podłączanie nowych.

OscarRyz
źródło
1
... ale które można po prostu zastąpić Comparator:)
BalusC
5

Odkryłem, że większość, jeśli nie wszystkie z tych odpowiedzi, polegają na klasie bazowej (Object) w implementacji porównywalnej lub posiadaniu porównywalnego interfejsu pomocnika.

Nie z moim rozwiązaniem! Poniższy kod pozwala porównać pole obiektu, znając jego nazwę ciągu. Możesz łatwo go zmodyfikować, aby nie używał nazwy, ale musisz ją ujawnić lub zbudować jeden z obiektów, z którymi chcesz porównać.

Collections.sort(anArrayListOfSomeObjectPerhapsUsersOrSomething, new ReflectiveComparator(). new ListComparator("name"));

public class ReflectiveComparator {
    public class FieldComparator implements Comparator<Object> {
        private String fieldName;

        public FieldComparator(String fieldName){
            this.fieldName = fieldName;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public int compare(Object object1, Object object2) {
            try {
                Field field = object1.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);

                Comparable object1FieldValue = (Comparable) field.get(object1);
                Comparable object2FieldValue = (Comparable) field.get(object2);

                return object1FieldValue.compareTo(object2FieldValue);
            }catch (Exception e){}

            return 0;
        }
    }

    public class ListComparator implements Comparator<Object> {
        private String fieldName;

        public ListComparator(String fieldName) {
            this.fieldName = fieldName;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public int compare(Object object1, Object object2) {
            try {
                Field field = object1.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                Comparable o1FieldValue = (Comparable) field.get(object1);
                Comparable o2FieldValue = (Comparable) field.get(object2);

                if (o1FieldValue == null){ return -1;}
                if (o2FieldValue == null){ return 1;}
                return o1FieldValue.compareTo(o2FieldValue);
            } catch (NoSuchFieldException e) {
                throw new IllegalStateException("Field doesn't exist", e);
            } catch (IllegalAccessException e) {
                throw new IllegalStateException("Field inaccessible", e);
            }
        }
    }
}
Kevin Parker
źródło
5

Możesz spróbować Guava Ordering :

Function<Item, Date> getStartDate = new Function<Item, Date>() {
    public Date apply(Item item) {
        return item.getStartDate();
    }
};

List<Item> orderedItems = Ordering.natural().onResultOf(getStartDate).
                          sortedCopy(items);
Vitalii Fedorenko
źródło
5

Możesz sortować za pomocą java 8

yourList.sort(Comparator.comparing(Classname::getName));

or

yourList.stream().forEach(a -> a.getBObjects().sort(Comparator.comparing(Classname::getValue)));
Poszukiwacz
źródło
3

Te fragmenty kodu mogą być przydatne. Jeśli chcesz posortować obiekt w moim przypadku, chcę posortować według VolumeName:

public List<Volume> getSortedVolumes() throws SystemException {
    List<Volume> volumes = VolumeLocalServiceUtil.getAllVolumes();
    Collections.sort(volumes, new Comparator<Volume>() {
        public int compare(Volume o1, Volume o2) {
            Volume p1 = (Volume) o1;
            Volume p2 = (Volume) o2;
            return p1.getVolumeName().compareToIgnoreCase(
                    p2.getVolumeName());
        }
    });
    return volumes;
}

To działa. Używam go w moim jsp.

Laura Liparulo
źródło
3

Z tej biblioteki tutaj można posortować listę obiektów niestandardowych w wielu kolumnach. Biblioteka korzysta z funkcji wersji 8.0. Próbka jest tam również dostępna. Oto próbka do zrobienia

SortKeys sortKeys = new SortKeys();
sortKeys.addField("firstName")
            .addField("age", true); // This (true) will sort the age descending

// Other ways to specify a property to the sorter are
//      .addField("lastName", String.class);
//      .addField("dob", Date.class, true);

// Instantiate a ListSorter
ListSorter listSorter = new ListSorter();

// Pass the data to sort (listToSort) and the "by keys" to sort (sortKeys)
List sortedList = (List<Person>) listSorter.sortList(listToSort, sortKeys);
Shriram M.
źródło
3

Możesz obejrzeć prezentację na Java Forum w Stuttgarcie w Niemczech w 2016 roku.

Tylko kilka slajdów używa języka niemieckiego, 99% treści to kod źródłowy Java oparty na języku angielskim; lubić

someCollection.sort(
  OurCustomComparator
    .comparing(Person::getName)
    .thenComparing(Person::getId)
);

gdzie OurCustomComparatorużywa domyślnych metod (i innych interesujących pomysłów). Jak pokazano, prowadząc do bardzo zwięzłego kodu, aby wybrać metodę pobierającą metodę sortowania; i super proste łączenie (lub cofanie) kryteriów sortowania.

Jeśli interesujesz się java8, znajdziesz tam wiele materiałów na początek.

GhostCat
źródło
3

Nowością od 1.8 jest metoda List.sort () zamiast metody Collection.sort (), więc można bezpośrednio wywołać mylistcontainer.sort ()

Oto fragment kodu, który demonstruje funkcję List.sort ():

List<Fruit> fruits = new ArrayList<Fruit>();
fruits.add(new Fruit("Kiwi","green",40));
fruits.add(new Fruit("Banana","yellow",100));
fruits.add(new Fruit("Apple","mixed green,red",120));
fruits.add(new Fruit("Cherry","red",10));

// a) using an existing compareto() method
fruits.sort((Fruit f1,Fruit f2) -> f1.getFruitName().compareTo(f2.getFruitName()));
System.out.println("Using String.compareTo(): " + fruits);
//Using String.compareTo(): [Apple is: mixed green,red, Banana is: yellow, Cherry is: red, Kiwi is: green]

// b) Using a comparable class
fruits.sort((Fruit f1,Fruit f2) -> f1.compareTo(f2));  
System.out.println("Using a Comparable Fruit class (sort by color): " + fruits);
// Using a Comparable Fruit class (sort by color): [Kiwi is green, Apple is: mixed green,red, Cherry is: red, Banana is: yellow]

Klasa Fruit to:

public class Fruit implements Comparable<Fruit>
{
    private String name;
    private String color;
    private int quantity;

    public Fruit(String name,String color,int quantity)
    { this.name = name; this.color = color; this.quantity = quantity; }

    public String getFruitName() { return name; }        
    public String getColor() { return color; }  
    public int getQuantity() { return quantity; }

    @Override public final int compareTo(Fruit f) // sorting the color
    {
        return this.color.compareTo(f.color);
    }     
    @Override public String toString()
    {   
        return (name + " is: " + color);
    }
} // end of Fruit class   
Norbert
źródło
2

Twoja klasa customComparator musi implementować java.util.Comparator, aby mogła być używana. musi także pomijać porównanie () ORAZ równa się ()

Compare () musi odpowiedzieć na pytanie: Czy obiekt 1 jest mniejszy, równy lub większy niż obiekt 2?

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

Vinny
źródło
1

Wolę ten proces:

public class SortUtil
{    
    public static <T> List<T> sort(List<T> list, String sortByProperty)
    {
            Collections.sort(list, new BeanComparator(sortByProperty));
            return list;
    }
}

List<T> sortedList = SortUtil<T>.sort(unsortedList, "startDate");

Jeśli lista obiektów ma właściwość o nazwie startDate, wywołujesz ją w kółko. Możesz je nawet połączyć startDate.time.

Wymaga to Twój obiekt, aby być Comparableco oznacza, że potrzebują compareTo, equalsoraz hashCodewdrożenie.

Tak, może być szybciej ... Ale teraz nie musisz tworzyć nowego Komparatora dla każdego rodzaju. Jeśli możesz zaoszczędzić czas deweloperów i zrezygnować z czasu wykonywania, możesz skorzystać z tego.

DDus
źródło
3
1, ta odpowiedź została podana 2 godziny wcześniej z podanym działającym kodem. Nie ma potrzeby ponownego publikowania tego samego rozwiązania i zaśmiecania forum, zwłaszcza że BeanComparator nie jest klasą standardową, więc nie jest to rozwiązanie, jeśli plakat nie wie o czym mówisz. Jeśli podoba Ci się oryginalna sugestia, możesz ją głosować i dodać komentarz, jeśli chcesz.
camickr
0

Za pomocą Java 8 use można zdefiniować za pomocą Comparatorjednego wierszaComparator.comparing()

Użyj dowolnego z następujących sposobów:

Opcja 1:

listToBeSorted.sort(Comparator.comparing(CustomObject::getStartDate));

Opcja 2:

Collections.sort(listToBeSorted, Comparator.comparing(CustomObject::getStartDate));
Sahil Chhabra
źródło
1
Wydaje się być duplikatem tej odpowiedzi sprzed 3 lat.
Basil Bourque
1
Nie do końca, tylko opcja 2 tutaj jest podobna do opcji 1 we wspomnianej odpowiedzi. Wydaje mi się, że dwie różne odpowiedzi mogą mieć przynajmniej pewne podobieństwa, jeśli są odpowiedzią na to samo pytanie.
Sahil Chhabra
0

Twoja klasa niestandardowa może implementować interfejs „Porównywalny”, który wymaga implementacji metody CompareTo. W metodzie CompareTo można następnie zdefiniować, co to znaczy, że obiekt jest mniejszy lub większy niż drugi obiekt. W twoim przykładzie może to wyglądać mniej więcej tak:

public class MyCustomClass implements Comparable<MyCustomClass>{

..........

 @Override
public int compareTo(MyCustomClass a) {
    if(this.getStartDate().before(a.getStartDate())){
        return -1;
    }else if(a.getStartDate().before(this.getStartDate())){
        return 1;
    }else {
        return 0;
    }
}

Liczba ujemna oznacza, że ten jest mniejszy niż w stosunku do obiektu. Pewna liczba dodatnia oznacza, że ta jest większa niż w stosunku do obiektu i zero oznacza, że obiekty są równe.

Następnie możesz użyć collections.sort (myList), aby posortować listę bez konieczności podawania komparatora. Ta metoda ma również tę zaletę, że sortuje rzeczy automatycznie, jeśli używasz posortowanych struktur danych kolekcji, takich jak TreeSet lub TreeMap.

Możesz sprawdzić ten artykuł, jeśli chcesz przeczytać więcej na temat porównywalnego interfejsu (ujawnienie: jestem autorem;)) https://nullbeans.com/the-java-comparable-interface-automatic-sort-of-collections/

Nullbeans
źródło
0

Możesz także użyć Springs PropertyComparator, jeśli masz tylko ścieżkę właściwości String do (zagnieżdżonej) właściwości, którą chcesz posortować:

List<SomeObject> list = ...;
PropertyComparator<HitWithInfo> propertyComparator = new PropertyComparator<>(
    "property.nested.myProperty", false, true);
list.sort(propertyComparator);

Wadą jest to, że ten komparator po cichu ignoruje właściwości, które nie istnieją lub są niedostępne i obsługuje to jako wartość zerową dla porównania. Oznacza to, że powinieneś dokładnie przetestować taki komparator lub jakoś zweryfikować istnienie ścieżki właściwości.

xtermi2
źródło
0

za pomocą interfejsu API strumienia java-8 możesz sortować ArrayListwedług:

 Comparator<Person> birthdayComparator = Comparator.comparing(Person::getBirthday);
 List<Person> sortedList = list.stream().sorted(birthdayComparator).collect(toList());
pero_hero
źródło