it-swarm.com.de

Sortieren einer ArrayList von Objekten mit einer benutzerdefinierten Sortierreihenfolge

Ich möchte eine Sortierfunktion für meine Adressbuchanwendung implementieren.

Ich möchte einen ArrayList<Contact> contactArray sortieren. Contact ist eine Klasse, die vier Felder enthält: Name, Privatnummer, Mobilnummer und Adresse. Ich möchte nach name sortieren.

Wie schreibe ich dazu eine benutzerdefinierte Sortierfunktion?

108
Sameera0

Hier ist ein Tutorial zum Bestellen von Objekten:

Obwohl ich einige Beispiele geben werde, würde ich empfehlen, es trotzdem zu lesen.


Es gibt verschiedene Möglichkeiten, einen ArrayListzu sortieren. Wenn Sie eine natürliche (Standard) Bestellung definieren möchten, dann Sie müssen Contactimplementieren lassen ComparableNAME _ . Angenommen, Sie möchten standardmäßig nach namesortieren, dann tun Sie Folgendes (Nullchecks wurden der Einfachheit halber weggelassen):

public class Contact implements Comparable<Contact> {

    private String name;
    private String phone;
    private Address address;

    public int compareTo(Contact other) {
        return name.compareTo(other.name);
    }

    // Add/generate getters/setters and other boilerplate.
}

damit du es einfach tun kannst

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

Collections.sort(contacts);

Wenn Sie eine extern steuerbare Reihenfolge definieren möchten (die die natürliche Reihenfolge außer Kraft setzt), müssen Sie eine ComparatorNAME _ erstellen:

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Now sort by address instead of name (default).
Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

Sie können die Comparatorname__s sogar in Contactselbst definieren, sodass Sie sie wiederverwenden können, anstatt sie jedes Mal neu zu erstellen:

public class Contact {

    private String name;
    private String phone;
    private Address address;

    // ...

    public static Comparator<Contact> COMPARE_BY_PHONE = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.phone.compareTo(other.phone);
        }
    };

    public static Comparator<Contact> COMPARE_BY_ADDRESS = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.address.compareTo(other.address);
        }
    };

}

welches wie folgt verwendet werden kann:

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Sort by address.
Collections.sort(contacts, Contact.COMPARE_BY_ADDRESS);

// Sort later by phone.
Collections.sort(contacts, Contact.COMPARE_BY_PHONE);

Und um das Top abzurunden, können Sie einen generischen Javabean-Komparator verwenden :

public class BeanComparator implements Comparator<Object> {

    private String getter;

    public BeanComparator(String field) {
        this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
    }

    public int compare(Object o1, Object o2) {
        try {
            if (o1 != null && o2 != null) {
                o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
                o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
            }
        } catch (Exception e) {
            // If this exception occurs, then it is usually a fault of the developer.
            throw new RuntimeException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
        }

        return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));
    }

}

was Sie wie folgt verwenden können:

// Sort on "phone" field of the Contact bean.
Collections.sort(contacts, new BeanComparator("phone"));

(wie Sie im Code sehen, sind möglicherweise Nullfelder bereits abgedeckt, um NPEs beim Sortieren zu vermeiden)

263
BalusC

Zusätzlich zu dem, was bereits veröffentlicht wurde, sollten Sie wissen, dass wir seit Java 8 unseren Code verkürzen und wie folgt schreiben können:

Collection.sort(yourList, Comparator.comparing(YourClass::getFieldToSortOn));

oder seit Liste haben jetzt sort Methode 

yourList.sort(Comparator.comparing(YourClass::getFieldToSortOn));

Erläuterung:

Seit Java 8 können funktionale Schnittstellen (Schnittstellen mit nur einer abstrakten Methode - sie können mehr Standard- oder statische Methoden haben) einfach implementiert werden:

Da Comparator<T> nur eine abstrakte Methode int compare(T o1, T o2) hat, handelt es sich um eine funktionale Schnittstelle.

Also statt (Beispiel aus @BalusCAntwort )

Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

wir können diesen Code reduzieren auf:

Collections.sort(contacts, (Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress());
});

Wir können dieses (oder irgendeines) Lambda durch Überspringen vereinfachen 

  • argumenttypen (Java wird sie anhand der Methodensignatur ableiten) 
  • oder {return ... }

Also statt 

(Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress();
}

wir können schreiben

(one, other) -> one.getAddress().compareTo(other.getAddress())

Außerdem verfügt Comparator über statische Methoden wie comparing(FunctionToComparableValue) oder comparing(FunctionToValue, ValueComparator), mit denen wir auf einfache Weise Komparatoren erstellen können, die bestimmte Werte von Objekten vergleichen. 

Mit anderen Worten, wir können den obigen Code als neu schreiben

Collections.sort(contacts, Comparator.comparing(Contact::getAddress)); 
//assuming that Address implements Comparable (provides default order).
24
Pshemo

Auf dieser Seite erfahren Sie alles Wissenswerte zum Sortieren von Sammlungen, z. B. ArrayList.

Grundsätzlich musst du

  • lassen Sie Ihre Contact-Klasse die Comparable-Schnittstelle mit .__ implementieren.
    • erstellen einer Methode public int compareTo(Contact anotherContact) darin.
  • Sobald Sie dies getan haben, können Sie einfach Collections.sort(myContactList);, .__ aufrufen.
    • dabei ist myContactListArrayList<Contact> (oder eine andere Sammlung von Contact).

Es gibt auch einen anderen Weg, die Erstellung einer Comparator-Klasse, und Sie können dies auch auf der verlinkten Seite nachlesen.

Beispiel:

public class Contact implements Comparable<Contact> {

    ....

    //return -1 for less than, 0 for equals, and 1 for more than
    public compareTo(Contact anotherContact) {
        int result = 0;
        result = getName().compareTo(anotherContact.getName());
        if (result != 0)
        {
            return result;
        }
        result = getNunmber().compareTo(anotherContact.getNumber());
        if (result != 0)
        {
            return result;
        }
        ...
    }
}
8
bguiz

BalusC und Bguiz haben bereits sehr vollständige Antworten zur Verwendung der in Java integrierten Komparatoren gegeben.

Ich möchte nur hinzufügen, dass Google-Collections eine Ordering -Klasse hat, die "leistungsfähiger" ist als die Standard-Komparatoren. Sie können coole Dinge tun, z. B. Sortierungen zusammensetzen, umkehren, sortieren, abhängig vom Ergebnis einer Funktion für Ihre Objekte ...

Hier ist ein Blogpost, der einige seiner Vorteile erwähnt.

5
Etienne Neveu

Sie müssen dafür sorgen, dass Ihre Kontaktklassen Comparable implementiert werden, und anschließend die compareTo(Contact)-Methode implementieren. Auf diese Weise kann Collections.Sort sie für Sie sortieren. CompareTo 'gibt für jede Seite, auf die ich verlinkt habe, eine negative Ganzzahl, Null oder eine positive Ganzzahl zurück, da dieses Objekt kleiner als, gleich oder größer als das angegebene Objekt ist.'

Wenn Sie beispielsweise nach Namen sortieren möchten (A bis Z), würde Ihre Klasse folgendermaßen aussehen:

public class Contact implements Comparable<Contact> {

    private String name;

    // all the other attributes and methods

    public compareTo(Contact other) {
        return this.name.compareTo(other.name);
    }
}
4
Kaleb Brasee

Mit lambdaj können Sie eine Sammlung Ihrer Kontakte (z. B. nach ihrem Namen) wie folgt sortieren

sort(contacts, on(Contact.class).getName());

oder über ihre Adresse:

sort(contacts, on(Contacts.class).getAddress());

und so weiter. Allgemeiner gesagt, bietet es ein DSL für den Zugriff und die Bearbeitung Ihrer Sammlungen auf verschiedene Weise, z. B. das Filtern oder Gruppieren von Kontakten nach bestimmten Bedingungen, das Sammeln einiger ihrer Eigenschaftswerte usw.

3
Mario Fusco

Ich habe es auf folgende Art und Weise gemacht. Zahl und Name sind zwei Arraylisten. Ich muss den Namen sortieren. Wenn bei einer Änderung die Arralisten-Reihenfolge geändert wird, ändert auch die Array-Liste ihre Reihenfolge.

public void sortval(){

        String tempname="",tempnum="";

         if (name.size()>1) // check if the number of orders is larger than 1
            {
                for (int x=0; x<name.size(); x++) // bubble sort outer loop
                {
                    for (int i=0; i < name.size()-x-1; i++) {
                        if (name.get(i).compareTo(name.get(i+1)) > 0)
                        {

                            tempname = name.get(i);

                            tempnum=number.get(i);


                           name.set(i,name.get(i+1) );
                           name.set(i+1, tempname);

                            number.set(i,number.get(i+1) );
                            number.set(i+1, tempnum);


                        }
                    }
                }
            }



}
0
sarath

verwenden Sie diese Methode:

private ArrayList<myClass> sortList(ArrayList<myClass> list) {
    if (list != null && list.size() > 1) {
        Collections.sort(list, new Comparator<myClass>() {
            public int compare(myClass o1, myClass o2) {
                if (o1.getsortnumber() == o2.getsortnumber()) return 0;
                return o1.getsortnumber() < o2.getsortnumber() ? 1 : -1;
            }
        });
    }
    return list;
}

`

und verwenden Sie: mySortedlist = sortList(myList);Kein Komparator muss in Ihrer Klasse nicht implementiert werden . Wenn Sie den umgekehrten Reihenfolge-Swap 1 und -1 verwenden

0
Bruno Mulas

Der Collections.sort ist eine gute Implementierung. Wenn Sie The Similar für Contact nicht implementiert haben, müssen Sie eine Comparator-Implementierung übergeben

Anmerkung:

Der Sortieralgorithmus ist ein modifizierter Mergesort (in dem die Zusammenführung weggelassen wird, wenn das höchste Element in der unteren Teilliste kleiner ist als das niedrigste Element in der oberen Teilliste). Dieser Algorithmus bietet eine garantierte n log (n) -Leistung. Die angegebene Liste muss modifizierbar sein, darf aber nicht skalierbar sein. Diese Implementierung speichert die angegebene Liste in einem Array, sortiert das Array und durchläuft die Liste, wobei jedes Element von der entsprechenden Position im Array zurückgesetzt wird. Dadurch wird die Leistung von n2 log (n) vermieden, die sich aus dem Versuch ergibt, eine verknüpfte Liste zu sortieren. 

Die Zusammenführungssortierung ist wahrscheinlich besser als die meisten Suchalgorithmen, die Sie ausführen können.

0
Joshua