# Arraylist Auto sortieren



## nasir (11. Mrz 2011)

Hallo,

Ich hätte da mal eine frage. Ich habe hier eine testklasse Auto erstellt:


```
public class Auto {
    private String name;
    private String farbe;
    private double benzintank;


    public Auto()
    {
        name = "";
        farbe = "";
        benzintank = 0.0;
    }

    public Auto(String name, String farbe, double benzintank)
    {
        this.name = name;
        this.farbe = farbe;
        this.benzintank = benzintank;
    }

    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public String getFarbe() {
        return farbe;
    }


    public void setFarbe(String farbe) {
        this.farbe = farbe;
    }


    public double getBenzintank() {
        return benzintank;
    }

    public void setBenzintank(double benzintank) {
        this.benzintank = benzintank;
    }

}
```

Nun möchte ich die Objekte der Klasse in nach Attribute sortieren. Also meine Testklasse lautet:


```
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        ArrayList<Auto> autoListe = new ArrayList<Auto>();
        autoListe.add(new Auto("Mercedes Benz", "schwarz", 50.0));
        autoListe.add(new Auto("Porsche", "rot", 45.0));
        autoListe.add(new Auto("VW", "weiss", 55.0));

        //Nach name sortieren ??

        //Nach Farbe sortieren ??

        //nach benzintank sortieren ??

    }

}
```

Ich hab mir das tutorial hier durchgelesen: http://www.java-forum.org/allgemeines/39510-arrays-listen-sortieren.html Leider habe ich verstanden das man bei Comparator oder Comparable leider nur nach einem Attribut sortieren. Ich will quasi aussuchen können, nach welches Attribut ich sortieren möchte, ohne 3 Compare Klassen für jedes Autoattribut zu erstellen.

Ich wäre furchtbar Dankbar, wenn man mir irgendwie helfen könnte.

Viele Grüße,

nasir


----------



## Marco13 (11. Mrz 2011)

EDIT: Oh-oh - tl;dr  Sorry 
http://www.java-forum.org/allgemeines/39510-arrays-listen-sortieren.html Darüber hinaus spezifische Fragen?

EDIT2: Also "aussuchen" kann man sich das nicht direkt, außer 
1. Mit Reflection (sollte man aber i.a. nicht machen...)
2. Indem man einen allgemeinen Zugriff auf die Attribute anbietet, nach denen sortiert werden soll. Sinngemäß(!!!) sowas wie 

```
public Comparable getCriterion(Attribute a) { /* gibt je nach 'Attribute' entweder farbe, name oder tank zurück */ }
```
Aber auch das ist nicht schön (zumindest nicht in diesem Fall). Was spricht dagegen, drei Comparatoren zu erstellen? Ggf. kann man die auch in eine Liste legen, und sich daraus einen Comparator zu bauen, bei dem man zwischen den dreien "umschalten" kann...


----------



## Dit_ (11. Mrz 2011)

```
public static void main(String[] args) {
        // TODO code application logic here
        ArrayList<Auto> autoListe = new ArrayList<Auto>();
        autoListe.add(new Auto("Mercedes Benz", "schwarz", 50.0));
        autoListe.add(new Auto("Porsche", "rot", 45.0));
        autoListe.add(new Auto("VW", "weiss", 55.0));

        //Nach name sortieren 
        Collections.sort(autoListe, new Comparator<Auto>() {

            @Override
            public int compare(Auto o1, Auto o2) {
                return o1.name.compareTo(o2.name);
            }
            
        });
 
        //Nach Farbe sortieren ?? ist jetzt klar
 
        //nach benzintank sortieren ??

    }
```


----------



## XHelp (11. Mrz 2011)

Man könnte dann auch die Comperatoren als statische Felder der Auto-Klasse implementieren, dann würde der Aufruf z.B.

```
Collections.sort(liste, Auto.NAME_COMPARATOR);
Collections.sort(liste, Auto.COLOR_COMPARATOR);
```
aussehen


----------



## nasir (11. Mrz 2011)

Ich habs jetzt so implementiert. Kürzer gehts wohl nicht. 

```
//Nach name sortieren
        Collections.sort(autoListe, new Comparator<Auto>() {

            public int compare(Auto first, Auto second) {
                if (first.getName() == null && second.getName() == null) {
                    return 0;
                }
                if (first.getName() == null) {
                    return 1;
                }
                if (first.getName() == null) {
                    return -1;
                }
                return first.getName().compareTo(second.getName());
            }
        });
        System.out.println(autoListe);

        //Nach Farbe sortieren
        Collections.sort(autoListe, new Comparator<Auto>() {

            public int compare(Auto first, Auto second) {
                if (first.getFarbe() == null && second.getFarbe() == null) {
                    return 0;
                }
                if (first.getFarbe() == null) {
                    return 1;
                }
                if (first.getFarbe() == null) {
                    return -1;
                }
                return first.getFarbe().compareTo(second.getFarbe());
            }
        });
        System.out.println(autoListe);

        //nach benzintank sortieren
        Collections.sort(autoListe, new Comparator<Auto>() {

            public int compare(Auto first, Auto second) {
                if (first.getBenzintank() < second.getBenzintank()) {
                    return -1;
                }
                if (first.getBenzintank() > second.getBenzintank()) {
                    return 1;
                }
                return 0;
            }
        });
        System.out.println(autoListe);
```

Ein toString wurde auch in der Autoklasse eingebaut.

Dankeschön!


----------



## XHelp (11. Mrz 2011)

Doch es geht kürzer. Zumindestmal der Benzintank-Vergleich:

```
public int compare(Auto first, Auto second) {
  return first.getBenzintank() - second.getBenzintank();
}
```
compare muss nicht unbedingt -1,0,1 zurückgeben. Egal welcher negative Wert wird als "kleiner" gedeutet.


----------



## Marco13 (11. Mrz 2011)

Wie soll das gehen, wenn Benzintank ein double ist? 

Ansonsten hat man da natürlich einige Möglichkeiten, je nachdem worauf man raus will...

```
/**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        ArrayList<Auto> autoListe = new ArrayList<Auto>();
        autoListe.add(new Auto("Mercedes Benz", "schwarz", 50.0));
        autoListe.add(new Auto("Porsche", "rot", 45.0));
        autoListe.add(new Auto("VW", "weiss", 55.0));

        //Nach name sortieren
        Collections.sort(autoListe, BY_NAME);
        System.out.println(autoListe);

        //Nach Farbe sortieren
        Collections.sort(autoListe, BY_COLOR);
        System.out.println(autoListe);

        //nach benzintank sortieren
        Collections.sort(autoListe, BY_GAS);
        System.out.println(autoListe);
    }

    private static final Comparator<Auto> BY_NAME = new Comparator<Auto>() {
            public int compare(Auto first, Auto second) {
                return doCompare(first.getName(), second.getName());
            }
        };

    private static final Comparator<Auto> BY_COLOR = new Comparator<Auto>() {
            public int compare(Auto first, Auto second) {
                return doCompare(first.getFarbe(), second.getFarbe());
            }
        };

    private static final Comparator<Auto> BY_GAS = new Comparator<Auto>() {
            public int compare(Auto first, Auto second) {
                return doCompare(first.getBenzintank(), second.getBenzintank());
            }
        };


    private static <T extends Comparable<? super T>> int doCompare(T t0, T t1)
    {
        if (t0 == null)
        {
            if (t1 == null)
            {
                return 0;
            }
            return 1;
        }
        if (t1 == null)
        {
            return -1;
        }
        return t0.compareTo(t1);
    }
```

(und noch sowas wie ein

```
public String toString()
    {
        return String.format("%15s %8s %6s", name, farbe, benzintank);
    }
```
in's Auto...)


----------



## XHelp (11. Mrz 2011)

Marco13 hat gesagt.:


> Wie soll das gehen, wenn Benzintank ein double ist?




```
double difference = first.getBenzintank() - second.getBenzintank();
return (int) (difference<0?Math.floor(difference):Math.ceil(difference));
```
:joke:

Ne, habe einfach nur nicht bemerkt, dass Benzintank als Double gespeichert wird.


----------

