2015-09-09 6 views
5

tun Lets nehme ich die folgende Liste von KartenWie kann ich eine sekundäre Sortierung auf einer Liste von Karten

[{id:1,count:2,name:xyz}, 
{id:2,count:3,name:def}, 
{id:3,count:2,name:abc}, 
{id:4,count:5,name:ghj} 
] 

habe ich zuerst von Graf diese Karte sortiert werden soll und dann nach Name:

Wunsch Ausgang:

[{id:3,count:2,name:abc}, 
{id:1,count:2,name:xyz}, 
{id:2,count:3,name:def}, 
{id:4,count:5,name:ghj} 
] 

ich habe versucht, die nach der ersten Sortierung durchzuführen, aber nicht in der Lage mit dem Namen sortiert werden, nachdem sie durch Zählung Sortierung

Collections.sort(list, new Comparator() { 
     public int compare(Object o1, Object o2) { 
      return ((Comparable) ((Map.Entry) (o1)).getValue()) 
      .compareTo(((Map.Entry) (o2)).getValue()); 
     } 
+1

Hat das sogar kompiliert? Raw 'Comparator' Typ benötigt' Object' Parameter, nicht 'Integer'. – Codebender

+0

Ich habe es nicht kompiliert. Ich habe nur eine Idee davon gegeben, was ich zu tun versuche –

+0

Was ist die Darstellung von Wert in Ihrer Karte. Ich nehme an, Key ist Integer. Aber wie speichern Sie die Werte? Weil für den gegebenen Schlüssel zwei Dinge im Wert sind. – YoungHobbit

Antwort

2

Mit Java 1.8, ich die neuen Vergleicher Methoden verwenden würde (obwohl der Mangel an Typ-Inferenz macht es notwendig, alle Arten zu erklären, zu reduzieren die lisibility):

final Comparator<Map<String, Comparable<Object>>> nameThenCountComparator = Comparator.<Map<String, Comparable<Object>>, Comparable<Object>> comparing(
      m -> m.get("name")).thenComparing(Comparator.<Map<String, Comparable<Object>>, Comparable<Object>> comparing(
      m -> m.get("count"))); 

Mit Java 1.7, würde ich wahrscheinlich eine chainedComparator (siehe Apache ComparatorUtils oder Guava des Ordering) und eine benutzerdefinierte MapValueComparator (es wahrscheinlich eine gemeinsam Bibliotheken ist, hat, aber es wird nicht gefunden). Dann erhält die gewünschte Bestellung gut lesbar:

class MapValueComparator implements Comparator<Map<String, Object>> { 
     private final String key; 

     public MapValueComparator(final String key) { 
      this.key = key; 
     } 

     @Override 
     public int compare(final Map<String, Object> o1, final Map<String, Object> o2) { 
      return ((Comparable<Object>)o1.get(key)).compareTo(o2.get(key)); 
     } 
    } 

    Comparator<Object> nameThenCountComparator = ComparatorUtils.chainedComparator(
      new MapValueComparator("name"), 
      new MapValueComparator("count") 
    ); 

Und dann verwenden Sie es (Java 7 oder 8):

final List<Map<String, Comparable<Object>>> list = null; 
Collections.sort(list, nameThenCountComparator); 

Rq: Sie sollen, wie in anderen Antworten erwähnt, prüfen nulls und abwesende Schlüssel im MapValueComparator.

4

list ‚s Typ Unter der Annahme List<Map<String,Object>> (es ist nicht klar, was der Typ des Wertes des Map ist, so habe ich Object), Ihre Comparator sollten zum Vergleich zwei Map<String,Object> Instanzen können.

Collections.sort(list, new Comparator<Map<String,Object>>() { 
     public int compare(Map<String,Object> o1, Map<String,Object> o2) { 
      // first compare o1.get("count") to o2.get("count") 
      // if they are equal, compare o1.get("name") to o2.get("name") 
      // don't forget to handle nulls (for example if either o1 or o2 is null 
      // or if any of the keys are not present in one or both of the maps) 
     } 
2

Wenn ich richtig verstehe, haben Sie eine List<Map<String, Object>>. Sie müssen eine benutzerdefinierte Comparator schreiben, um es zu sortieren. Dort können Sie jeden Eintrag einzeln vergleichen (Fehler für bravity entfernt Abwicklung):

public class ListMapComparator implements Comparator<List<Map<String, Object>>> { 

    @Override 
    public in compare (List<Map<String, Object>> l1, List<Map<String, Object>> l2) { 
     Integer count1 = (Integer)l1.get("count"); 
     Integer count2 = (Integer)l2.get("count"); 
     int comp = count1.compare(count2); 
     if (comp != 0) { 
      return comp; 
     } 

     String name1 = (String)l1.get("name"); 
     String name2 = (String)l2.get("name"); 
     return name1.compare(name2); 
    }  
} 
Verwandte Themen