# ArrayList sortieren (mehrere Kriterien)



## Camino (8. Feb 2009)

Hallo,

wie kann ich denn meinen (unten angezeigten) Comparator so ändern, dass ich meine ArrayList nach mehreren Kriterien sortieren kann, z.B. erst nach Nachname und dann nach Vorname (falls evtl. gleiche Nachnamen mehrmals vorkommen)? Oder muss ich für Nachnamen und Vornamen jeweils einen Comparator schreiben und diese dann nacheinander anwenden? Das Sortieren nach nur einem Kriterium (Nachname) klappt so schon mal. Ich hatte auch irgendwo gelesen, dass Collator zum Sortieren von Strings besser wäre. Hab aber leider bisher noch kein Beispiel gefunden, wie ich den Collator anstatt dem Comparator benutze.

Hier die Comparator-Klasse:

```
import java.util.Comparator;


public class MyListComparator implements Comparator<Player> {
	
	    public int compare( Player a, Player b ) {

	    	String name1 = ((Player) a).getLastName();
	        String name2 = ((Player) b).getLastName();
	        return name1.compareTo(name2);
	    }
	       
}
```

Aufgerufen wird der Comparator in der Datenklasse so:

```
...
Comparator<Player> comparator = new MyListComparator();
java.util.Collections.sort( playerList, comparator );
...
```

Vielen Dank schonmal im voraus
Camino


----------



## SlaterB (8. Feb 2009)

mach das so:

public int compare( Player a, Player b ) {

          int c = ...; // erstes compare
          if (c != 0) {
 return c;
}
// hier nun neues c aus Vornamen berechnen usw.
       }


edit
zu Collator:
http://www.google.de/search?hl=de&q=Collator+list+sort+example&btnG=Google-Suche&meta=


----------



## Camino (9. Feb 2009)

Hab das jetzt mal so umgeschrieben:

```
import java.util.Comparator;

public class MyListComparator implements Comparator<Player> {
	
	    public int compare( Player a, Player b ) {

	    	String lastName1 = ((Player) a).getLastName();
	        String lastName2 = ((Player) b).getLastName();
	        String firstName1 = ((Player) a).getFirstName();
	        String firstName2 = ((Player) b).getFirstName();
	        
	        int c1 = lastName1.compareTo(lastName2); // erstes compare
	        if (c1 != 0) {
	        	return c1;
	        } 
	        
	        int c2 = firstName1.compareTo(firstName2); // zweites compare
	        return c2;
  
	    }
	       
}
```

Scheint erstmal so, als würde es funktionieren. Muss das morgen mal mit mehreren neuen Einträgen testen. Das mit dem Collator muss ich mir auch noch mal genauer anschauen.

Danke
Camino


----------



## Camino (9. Feb 2009)

OK, das Sortieren von Strings mit dem Comparator ist wirklich nicht so toll. Umlaute werden nach hinten sortiert (z.B. "Hab...", "Hen...", "Hum...", "Hän...") und Kleinbuchstaben kommen erst nach allen Grossbuchstaben. Scheint mit dem Collator wohl besser zu funktionieren. Aber ich hab jetzt schon gesucht und nicht rausgefunden, wie es geht. Vielleicht kann mir ja wer nen Tipp geben. Wie kann ich dem Collator sagen, nach welchem/n Werten in den Objekten er sortieren soll?


```
Collator col = Collator.getInstance(); 
java.util.Collections.sort( playerList, col );
```

Da bekomme ich die Fehlermeldung:


> Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: Player cannot be cast to java.lang.String



In der ArrayList playerList sind Objekte der Klasse Player (mit mehreren Strings) drin.


----------



## Camino (10. Feb 2009)

OK, neuer Versuch, den ich nun gefunden habe...

Der Collator:

```
import java.text.CollationKey;
import java.text.Collator;
import java.util.Comparator;


public class CollatorComparator 
        implements Comparator<Player> {
      Collator collator = Collator.getInstance();
      public int compare(Player a, Player b) {
        CollationKey key1 = collator.getCollationKey(
          a.getLastName());
        CollationKey key2 = collator.getCollationKey(
          b.getLastName());
        return key1.compareTo(key2);
      }
    }
```

Wird so aufgerufen:

```
CollatorComparator comp = new CollatorComparator();
Collections.sort(playerList, comp);
```

Scheint erstmal prima zu funktionieren...


----------



## SlaterB (10. Feb 2009)

der normale Weg wäre wohl etwas in der Art von

public int compare(Player a, Player b) {
        int c = collator.compare(string1, string2);
// statt: int c = string1.compareTo(string2);

        ..
      }


----------



## Camino (10. Feb 2009)

OK, hab das mal so umgebaut und auch die Sortierung nach dem 2. Kriterium (Vorname) eingesetzt. Vielen Dank für die Hilfe...


```
import java.text.Collator;
import java.util.Comparator;


public class CollatorComparator 
        implements Comparator<Player> {
      Collator collator = Collator.getInstance();
            
      public int compare(Player a, Player b) {
    	  
    	  int c1 = collator.compare(a.getLastName(), b.getLastName());
    	  
	        if (c1 != 0) {
	        	return c1;
	        } 
	        
	      int c2 = collator.compare(a.getFirstName(), b.getFirstName());
	        return c2;
    	    
      }
    }
```


----------

