Ganymed Geschrieben 7. Juli 2016 Geschrieben 7. Juli 2016 Hallo zusammen, ich stehe etwas auf dem Schlauch und sämtliche Beispiele, die ich gefunden habe, brachten mich nicht wirklich weiter, da sie mein Ausgangsproblem nicht behandelten. Folgendes: Ich habe ein eigenes Objekt erstellt, welches ich nun sortieren möchte. Im Grunde beinhaltet das Objekt 2 Attribute, welche im Kern Integerwerte beinhalten (in Wirklichkeit sind da weitere BOs drin, will es aber hier einfach halten). Also Attribut 1 = Typ Integer Attribut 2 = Typ Integer Ich habe eine compateTo() Methode geschrieben, sowie hashCode() und equals() implementiert. Was ich irgendwie nicht abgebildet bekomme ist folgendes: Ich möchte Attribut 2 absteigend sortieren und innerhalb der absteigenden Sortierung die Werte von Attribut 1 aufsteigend sortieren. Ich bekomme aber immer nur eine Richtung sortiert, nie beide. Beispiel: Ich habe eine Liste mit folgenden Wertepaaren 100 / 7 110 / 7 120 / 3 130 / 8 099 / 8 080 / 2 Ich bräuchte jetzt folgende Sortierung: 099 / 8 130 / 8 100 / 7 110 / 7 120 / 3 080 / 2 Bekomme ich das mit nem compareTo() oder einem Comperator überhaupt hin? Hat wer ein Beispiel / Tutorial für mich, was mir hier weiterhelfen könnte? Ich finde immer nur entweder simple Listen mit einem Wert oder es wird alles in eine Richtung sortiert. Gruß Ganymed Zitieren
Hexagon Geschrieben 7. Juli 2016 Geschrieben 7. Juli 2016 Moin, vielleicht hilft Dir das (Ist leider C++): std::vector<std::pair<int, int>> v; v.push_back({ 100 , 7 }); v.push_back({ 110 , 7 }); v.push_back({ 120 , 3 }); v.push_back({ 130 , 8 }); v.push_back({ 99 , 8 }); v.push_back({ 80 , 2 }); std::sort(v.begin(), v.end(), [](auto l, auto r) { return l.first < r.first; }); std::sort(v.begin(), v.end(), [](auto l, auto r) { return l.second > r.second; }); So etwas ähnliches sollte doch in Java auch gehen, oder? Zitieren
Ganymed Geschrieben 7. Juli 2016 Autor Geschrieben 7. Juli 2016 Auseinandernehmen und dann neu zusammenstecken wollte ich halt nicht, sondern über die Java-Methoden machen, das fände ich eleganter. Ist halt die Frage, wie mächtig die sind oder ob das wirklich nur auf das beschränkt ist, was man so findet. Vielleicht muss man das ja nur erweitern / anders aufrufen und schon gehts. Zitieren
arlegermi Geschrieben 7. Juli 2016 Geschrieben 7. Juli 2016 Das CompareTo müsste ca. so aussehen: public int CompareTo(BO other) { if (Value2 == other.Value2) { return Value1.CompareTo(other.Value1); } else { return Value2.CompareTo(other.Value2) * -1; } } Hab's jetzt nicht getestet, aber das Prinzip sollte stimmen. Zitieren
Gast Uhu Geschrieben 7. Juli 2016 Geschrieben 7. Juli 2016 (bearbeitet) vor 2 Stunden schrieb Ganymed: Bekomme ich das mit nem compareTo() oder einem Comperator überhaupt hin? Jein. Wichtig zu verstehen ist, dass sowohl compareTo() als auch ein Comperator dafür gedacht sind, lediglich zwei Objekte zu vergleichen. Du bildest hier mit also die Sortierungsbedingung ab die komplexer ist als bspw. nur < oder >. Man spricht auch davon, dass man nicht nach einer natürlichen Bedingung vergleicht. Das heißt in deinem Vergleich bildest du nur die Wertigkeit deiner Objekte ab => Es wird nur nach Attribut 1 verglichen, wenn Attribut 2 gleich ist. Die eigentliche Sortierung muss allerdings eine Sortierungsfunktion vornehmen. Deswegen kannst du Sortierungsklassen (siehe Collections.sort) neben einer Liste deiner Objekte auch einen Comperator übergeben, der dafür sorgt, dass die übergeben Objektliste Anhand deiner definierten Bedingungen im Comperator verglichen werden. Siehe hier zu auch: http://docs.oracle.com/javase/tutorial/collections/interfaces/order.html Einfach deine Liste sequenziell abarbeiten mit CompareTo() oder einem Comperator führt nicht zu einer vollständigen Sortierung, weil du immer nur die nebeneinander stehenden Wertepaare miteinander verglichen hast. Bearbeitet 7. Juli 2016 von Uhu Zitieren
stefan.macke Geschrieben 7. Juli 2016 Geschrieben 7. Juli 2016 import java.util.ArrayList; import java.util.Comparator; import java.util.List; public class Sortierung { private static class MeinObjekt { private final int wert1; private final int wert2; public MeinObjekt(final int wert1, final int wert2) { this.wert1 = wert1; this.wert2 = wert2; } private int getWert1() { return wert1; } private int getWert2() { return wert2; } @Override public String toString() { return String.format("%s / %s", getWert1(), getWert2()); } } public static void main(final String[] args) { final List<MeinObjekt> objekte = new ArrayList<>(); objekte.add(new MeinObjekt(100, 7)); objekte.add(new MeinObjekt(110, 7)); objekte.add(new MeinObjekt(120, 3)); objekte.add(new MeinObjekt(130, 8)); objekte.add(new MeinObjekt(99, 8)); objekte.add(new MeinObjekt(80, 2)); System.out.println("Vorher -----------------------------"); objekte.forEach(System.out::println); System.out.println("Nachher ----------------------------"); final Comparator<MeinObjekt> nachWert2Absteigend = (mo1, mo2) -> Integer.compare(mo2.getWert2(), mo1.getWert2()); final Comparator<MeinObjekt> nachWert1Aufsteigend = (mo1, mo2) -> Integer.compare(mo1.getWert1(), mo2.getWert1()); objekte.stream() .sorted( nachWert2Absteigend.thenComparing(nachWert1Aufsteigend)) .forEach(System.out::println); } } Ausgabe: Vorher ----------------------------- 100 / 7 110 / 7 120 / 3 130 / 8 99 / 8 80 / 2 Nachher ---------------------------- 99 / 8 130 / 8 100 / 7 110 / 7 120 / 3 80 / 2 Zitieren
Ganymed Geschrieben 8. Juli 2016 Autor Geschrieben 8. Juli 2016 (bearbeitet) @Uhu Ich lese mir das mal durch. @stefan.macke Lambda Expression kann ich leider nicht verwenden. Ich arbeite mit 1.6. Habe ich auch noch nicht verwendet, so dass ich das ehrlich gesagt nicht lesen und verstehen kann. Habe viel davon gehört, würde auch gerne mal eine verständliche Einführung dazu lesen (gerne Deutsch!) Bearbeitet 8. Juli 2016 von Ganymed Zitieren
Ganymed Geschrieben 8. Juli 2016 Autor Geschrieben 8. Juli 2016 vor 16 Stunden schrieb arlegermi: Das CompareTo müsste ca. so aussehen: public int CompareTo(BO other) { if (Value2 == other.Value2) { return Value1.CompareTo(other.Value1); } else { return Value2.CompareTo(other.Value2) * -1; } } Hab's jetzt nicht getestet, aber das Prinzip sollte stimmen. Hey, super, das hat funktioniert! Nur "CompareTo" sollte überall "comapreTo" heißen, falls jemand das auch mal nutzen möchte. Vielen Dank an alle! arlegermi reagierte darauf 1 Zitieren
Ganymed Geschrieben 8. Juli 2016 Autor Geschrieben 8. Juli 2016 vor 6 Minuten schrieb Ganymed: @Uhu Ich lese mir das mal durch, das könnte hilfreich sein! @stefan.macke Lambda Expression kann ich leider nicht verwenden. Ich arbeite mit 1.6. Habe ich auch noch nicht verwendet, so dass ich das ehrlich gesagt nicht lesen und verstehen kann. Habe viel davon gehört, würde auch gerne mal eine verständliche Einführung dazu lesen (gerne Deutsch!) Zitieren
arlegermi Geschrieben 8. Juli 2016 Geschrieben 8. Juli 2016 vor 1 Stunde schrieb Ganymed: Nur "CompareTo" sollte überall "comapreTo" heißen, falls jemand das auch mal nutzen möchte. Oh richtig, Java. Das kommt vom vielen C# Zitieren
Ganymed Geschrieben 8. Juli 2016 Autor Geschrieben 8. Juli 2016 Ach ja, und die Zeile if (Value2 == other.Value2) Lieber mit equals() vergleichen! Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.