Das Sortieren einer ArrayList von Objekten mithilfe einer benutzerdefinierten Reihenfolge Sortieren.

StackOverflow https://stackoverflow.com/questions/1814095

Frage

Ich bin auf der Suche zu implementieren, die eine Art Funktion für meine Adressbuch-Anwendung.

Ich möchte sozusagen ein ArrayList<Contact> contactArray. Contact ist eine Klasse, die enthält vier Felder:name, Haus Nummer, Handy Anzahl und Adresse.Ich möchte sozusagen auf name.

Wie erstelle ich eine benutzerdefinierte Sortierfunktion, dies zu tun?

War es hilfreich?

Lösung

Hier ist ein tutorial, über die Bestellung und Objekte:

Obwohl ich einige Beispiele nennen, würde ich empfehlen, es zu Lesen sowieso.


Es gibt verschiedene Wege, um eine Art ArrayList.Wenn Sie definieren wollen Natürliche (Standard) Bestellung, dann müssen Sie lassen Sie Contact Umsetzung Comparable.Unter der Annahme, dass die Sie Sortieren möchten, die standardmäßig auf name, dann tun Sie (nullchecks 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.
}

so dass Sie tun können

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

Collections.sort(contacts);

Wenn Sie wollen, definieren Sie eine extern steuerbar Bestellung (das überschreibt die Natürliche Reihenfolge), dann müssen Sie zum erstellen einer Comparator:

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 sogar definieren die Comparators im Contact selbst, so dass können Sie diese wiederverwenden, anstatt Sie neu zu erstellen jedes mal:

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);
        }
    };

}

die kann wie folgt eingesetzt werden:

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 Sahne oben ab, Sie könnte erwägen, zu verwenden eine generic javabean-Komparator:

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 können Sie verwenden, wie folgt vor:

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

(wie Sie im code sehen, der möglicherweise null-Felder sind bereits abgedeckt, um zu vermeiden NPE ist beim Sortieren)

Andere Tipps

Zusätzlich zu dem, was bereits geschrieben Sie sollten da Java 8 wissen, dass wir unseren Code verkürzen können und schreiben Sie es mögen:

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

oder seit Liste hat jetzt sort Methode

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

Erklärung:

Da Java 8, funktionale Schnittstellen (Interfaces mit nur einem abstrakten Methode - sie können mehr Ausfall- oder statische Methoden haben) können leicht implementiert werden:

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

So statt (zB von @BalusC Antwort )

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:

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

Wir können dies vereinfachen (oder überhaupt) Lambda durch Überspringen

  • Argumenttypen (Java wird sie schließen, basierend auf Methodensignatur)
  • oder {return ... }

So anstelle von

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

Wir können schreiben

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

Auch jetzt Comparator hat statische Methoden wie comparing(FunctionToComparableValue) oder comparing(FunctionToValue, ValueComparator), die wir leicht Comparators nutzen könnten zu schaffen, die einige spezifische Werte von Objekten vergleichen sollte.

Mit anderen Worten, wir können über Code umschreiben als

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

Diese Seite sagt Ihnen alles, was Sie brauchen, um Informationen über das Sortieren Sammlungen, wie Arraylist.

Im Grunde müssen Sie

  • machen Ihre Contact Klasse die Comparable Schnittstelle implementieren durch
    • ein Verfahren public int compareTo(Contact anotherContact) in ihm zu schaffen.
  • Sobald Sie dies tun, können Sie einfach Collections.sort(myContactList); nennen,
    • wo myContactList ArrayList<Contact> (oder jede andere Sammlung von Contact) ist.

Es gibt eine andere Art und Weise als auch, an denen eine Vergleicher-Klasse erstellen, und Sie können auch über die von der verlinkten Seite zu lesen.

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;
        }
        ...
    }
}

BalusC und bguiz haben bereits sehr umfassende Antworten auf gegeben, wie Built-in verwenden Java Comparators.

Ich will nur, dass Google-Sammlungen hinzufügen hat eine Klasse Bestellung, die mehr ist "mächtig" als die Standard-Komparatoren. Es könnte Check-out wert sein. Sie können coole Dinge tun wie Ordnungen Compoundierung, Wende- sie, Bestellung in Abhängigkeit von einem Ergebnis der Funktion für Ihre Objekte ...

Hier ist eine Blog-Post, die einige seiner Vorteile erwähnt.

Sie müssen Ihre Kontakt Klassen implementieren vergleichbar machen , und dann die compareTo(Contact) Methode implementieren. Auf diese Weise wird die Collections.sort Lage sein, sie für Sie zu sortieren. I pro der Seite verknüpft, compareTo ‚liefert eine negative ganze Zahl, Null oder eine positive ganze Zahl, wie dieses Objekt kleiner als, gleich oder größer als das angegebenen Objekt.‘

Zum Beispiel, wenn Sie nach Namen (A bis Z), die Klasse würde wie folgt aussehen sortieren wollen:

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);
    }
}

Durch die Verwendung von lambdaj können Sie eine Sammlung Ihrer Kontakte sortieren (zum Beispiel durch ihre nennen) wie folgt

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

oder durch ihre Adresse:

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

und so weiter. Mehr im Allgemeinen, bietet es einen DSL zugreifen und Ihre Sammlungen in vielerlei Hinsicht zu manipulieren, wie Filter oder Gruppierung Ihrer Kontakte basierend auf bestimmten Bedingungen aggregieren einige ihrer Eigenschaftswerte, etc.

Die Collections.sort ist eine gute Art Umsetzung. Wenn Sie nicht die vergleichbaren für Contact implementiert haben, müssen Sie in einem Vergleicher Umsetzung

Hinweis:

  

Der Sortieralgorithmus ist ein modifiziertes mergesort (in dem die Zusammenführung, wenn das höchste Element in den niedrigen sublist weggelassen wird, ist kleiner als das niedrigste Element im Hoch sublist). Dieser Algorithmus bietet garantiert n log (n) Leistung. Die angegebene Liste muss modifizierbar, müssen aber nicht veränderbar sein. Diese Implementierung Dumps der angegebenen Liste in ein Array sortiert das Array und iteriert über die Liste jedes Element von der entsprechenden Position in der Anordnung zurückzusetzen. Dies vermeidet die n2 log (n) Leistung, die von dem Versuch zu sortieren eine verkettete Liste an Ort und Stelle zur Folge hätte.

Der Mergesort ist wahrscheinlich besser als die meisten Suchalgorithmus Sie tun können.

Ich habe es durch die folgende Weise. Nummer und Name sind zwei Arraylist. Ich habe Namen zu sortieren .Wenn jede Änderung nennen passiert arralist, um dann auch die Zahl Arraylist seine Reihenfolge ändern.

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);


                        }
                    }
                }
            }



}

Mit dieser 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 Verwendung: mySortedlist = sortList(myList); Keine Notwendigkeit Komparator in Ihrer Klasse zu implementieren. Wenn Sie möchten, um Swap-1 und -1 invers

Sie sollten die Arrays.sort-Funktion verwenden. Die darin enthaltenen Klassen sollten vergleichbare implementieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top