Collections.sort klappt nicht

SolvencyII

Mitglied
Hallo!

Eine weitere Frage, die ich habe, bezüglich des gleichen Programms.

Ich will ein Array zweimal nach verschiedenen Spalten sortieren. Nach Country klappt schon mal.
Code:
        List<Flughafen> flughaefen = leseCsvDaten();
        Collections.sort(flughaefen, (a1,a2) -> {return a1.getCountry().compareTo(a2.getCountry());});
Jetzt soll es auch noch nach "Airportcode" sortiert werden und daran scheitert es.
Code:
        // Einlesen der Daten in eine map Datenstruktur
        List<Flughafen> flughaefen = leseCsvDaten();
        Collections.sort(flughaefen, (o1,o2) -> {return o1.getAirportcodes().compareTo(o2.getAirportcodes());});
Da kriege den Fehler
Code:
Exception in thread "main" java.lang.NullPointerException
    at FlughafenProjekt.lambda$AirportSuche$1(FlughafenProjekt.java:88)
    at java.util.TimSort.countRunAndMakeAscending(TimSort.java:360)
    at java.util.TimSort.sort(TimSort.java:234)
    at java.util.Arrays.sort(Arrays.java:1512)
    at java.util.ArrayList.sort(ArrayList.java:1454)
    at java.util.Collections.sort(Collections.java:175)
    at FlughafenProjekt.AirportSuche(FlughafenProjekt.java:88)
    at FlughafenProjekt.run(FlughafenProjekt.java:44)
    at FlughafenProjekt.main(FlughafenProjekt.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

Process finished with exit code 1
Hat jemand eine Ahnung woran das liegt? Wäre echt dankbar um einen Tipp/Hilfe.

Gruß, SII
 

SolvencyII

Mitglied
Vermutlich ist o1.getAirportcodes()[icode] [icode]null, mehr verrät dir der Debugger oder ein sout



Nein, du willst kein Array nicht nach Spalten sortieren, du willst eine Liste nach Attributen der enthaltenen Objekte sortieren.
Danke. Stimmt, die Beschreibung ist noch gewöhnungsbedürftig für mich.

Dein Tipp stimmt. Der Airportcode kann "null" bzw. nicht vorhanden sein. Wie kann ich das in meiner lambda expression berücksichtigen? hätte intuitiv o1 und o2 getestet, aber die werden dann ja nicht sortiert...
 

SolvencyII

Mitglied
Entweder selber prüfen, oder die statische Funktionen aus Comparator nutzen, zB Comparator.nullsFirst
Danke für den Tipp. Jetzt muss ich es nur noch in meinen Code einbauen.

Leider hat es aber bei mir nicht geklappt. Ich habe es verschieden ausprobiert, zum Beispiel kriege ich mit dem Code
Code:
// Einlesen der Daten in eine map Datenstruktur
        List<Flughafen> flughaefen = leseCsvDaten();
        Collections.sort(flughaefen, Comparator.nullsFirst((o1,o2) -> {return o1.getAirportcodes().compareTo(o2.getAirportcodes());}));
weiterhin einen Fehler. Meine lambda expression ist ja mein Comparator...daher dachte ich, dass es so klappen muss.
 

mrBrown

Super-Moderator
Mitarbeiter
Der nullsFirst-Comparator bekommt jetzt deine Flughäfen übergeben, da würde null vor einem Flughafen einsortiert werden. Flughäfen sind allerdings nicht null, sondern airportcodes. Du musst deinen Comparator also so umbauen, dass nullsFirst-Comparator die airportcodes übergeben bekommt.

Du machst es dir vermutlich leichter, den Comparator erstmal in eine extra Methode auszulagern (bzw ihn auf dem Java-7 Weg zu implementieren), je nachdem wie gut du mit Lambdas und Methoden-Referenzen klar kommst...
 

SolvencyII

Mitglied
Danke! Ich habe den Comparator in einer Methode ausgelagert. Es sieht nun so aus
Code:
 public enum Orden implements Comparator<Flughafen> {
        ByAirportcodes {
            public int compare(Flughafen o1, Flughafen o2) {
                if (o1.getAirportcodes() == null && o2.getAirportcodes() == null)
                    return 0;
                if (o1.getAirportcodes() == null)
                    return 1;
                else if (o2.getAirportcodes() == null)
                    return -1;
                return o1.getAirportcodes().compareTo(o2.getAirportcodes());
            }
        }
        }
und es klappt. Danke!
 

mrBrown

Super-Moderator
Mitarbeiter
Das ganze kann man jetzt noch vereinfachen ;)

Code:
 public enum Orden implements Comparator<Flughafen> {
        ByAirportcodes {
            public int compare(Flughafen o1, Flughafen o2) {
                  return Comparator.nullsFirst(Comparator.naturalOrder())
                           .compare(o1.getAirportcodes(),o2.getAirportcodes());
        }
    }
 

Neue Themen


Oben