compareTo Methode überschreiben

Simon16

Neues Mitglied
Hallo zusammen,
Ich habe eine Arrayliste von einer anderen Klasse gemacht wo verschiedenste Variablen reingespeichert werden.
Am Schluss möchte ich die Arrayliste mit Collections.sort(Arraylist); sortieren.
Da müsste ich in der Klasse von der Arrayliste eine compareTo Methode überschreiben damit es richtig sortiert wird.
Wie schaut so eine Methode aus
 
Beste Antwort
Ich benutze immer einen Comparator. zB:
Java:
package model;
import java.util.Comparator;
public class DbComparator1 implements Comparator<SatzDatenbank>
{
    @Override
    public int compare(SatzDatenbank o1, SatzDatenbank o2)
    {
        String srv1 = o1.getSrv();
        String srv2 = o2.getSrv();
        String db1 = o1.getDb();
        String db2 = o2.getDb();
        int erg = db1.compareToIgnoreCase(db2);
        if (erg == 0)
        {
            erg = srv1.compareToIgnoreCase(srv2);
        }
        return erg;
    }
}
der Aufruf sieht dann so aus:
Java:
ArrayList<SatzDatenbank> al = o.getDatenbankliste();
   if (sort == 1) al.sort(new DbComparator1());
Ich benutze immer einen Comparator. zB:
Java:
package model;
import java.util.Comparator;
public class DbComparator1 implements Comparator<SatzDatenbank>
{
    @Override
    public int compare(SatzDatenbank o1, SatzDatenbank o2)
    {
        String srv1 = o1.getSrv();
        String srv2 = o2.getSrv();
        String db1 = o1.getDb();
        String db2 = o2.getDb();
        int erg = db1.compareToIgnoreCase(db2);
        if (erg == 0)
        {
            erg = srv1.compareToIgnoreCase(srv2);
        }
        return erg;
    }
}
der Aufruf sieht dann so aus:
Java:
ArrayList<SatzDatenbank> al = o.getDatenbankliste();
   if (sort == 1) al.sort(new DbComparator1());
 
Beste Antwort
Ich benutze immer einen Comparator.
Ja, den Comparator nutze ich auch immer gerne, aber doch bitte nicht so!

Deinen Comparator muss man gar nicht so als Klasse schreiben, denn Comparator bietet die Funktionalität um das ganz einfach auszudrücken:
Java:
Comparator<SatzDatenbank>
    .comparing(SatzDatenbank::getDb)
    .thenComparing(SatzDatenbank::getSrv)

Das ist doch viel kürzer und viel einfacher zu lesen, oder?

Und das ändert natürlich nichts daran, dass eine Klasse, die eine natürliche Ordnung haben soll, Comparable<T> implementiert. Dann hat die Klasse ein public static Comparator<T> NATURAL_ORDER_COMPARATOR = Comparator.comparing(....).thenComparing(...);
Und die Methode compareTo ruft dann nur NATURAL_ORDER_COMPARATOR.compare(.....) auf.
 
So oder so ähnlich wie im Post von MisterBu sind all die Vergleiche im originalen Java Code implementiert, bevor man Comparatoren zusammenhängen konnte. Nicht schön, dafür aber effizient. Unterm Strich dürfte auf modernen Systemen beides gleich schnell sein, die Auslastung für die zuammengehängten Komparatoren aber höher. Es werden bei funktionalen Aufrufen in den meisten Fällen noch zusätzliche Tests durchgeführt. Auf der Haben-Seite ist allerdings zu vermerken, dass der Compiler hier optimieren kann, während er das bei der "Low-Level" Version für gewöhnlich nicht kann.

Wenn man's auf die unschöne alte Art machen möchte, würd ich allerdings den Code so umstellen, dass er leichter erweiterbar ist.
Java:
    public int compare(SatzDatenbank o1, SatzDatenbank o2) {
        int erg = o1.getDb().compareToIgnoreCase(o2.getDb());
        if (erg != 0) {
            return erg;
        }
        erg = o1.getSrv().compareToIgnoreCase(o2.getSrv());
        if (erg != 0) {
            return erg;
        }
        erg = ...;
        if (erg != 0) {
            return erg;
        }
        erg = ...;
        return erg;
    }


Die compareTo-Methode zu überschreiben, ist natürlich auch eine Möglichkeit. Welche Ergebnisse sie für welchen Fall liefern soll, ist im Interface definiert. (kleiner 0, gleich 0, größer 0).
 

Zurück
Oben