How to perform secondary sorting by map list

Suppose I have the following list of cards

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

First I want to sort this card by account, and then by name:

Output Required:

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

I tried the following sort, but could not sort the name after sorting by account

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

With Java 1.8, I would use the new Comparator methods (although the lack of type inference makes it necessary to declare all types, reducing the possibility of leasing):

  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"))); 

With Java 1.7, I would probably use cainedComparator (see Apache ComparatorUtils or Guava Ordering ) and a custom MapValueComparator (there is probably one of the common libraries, but could not find it). Then the desired order becomes readable:

  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") ); 

And then use it (Java 7 or 8):

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

Rq: you should, as pointed out in other answers, check for zeros and missing keys in MapValueComparator.

+2
source

Assuming the list type is List<Map<String,Object>> (it's not clear what type of Map value is, so I used Object ), your Comparator should be able to compare two instances of Map<String,Object> .

 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) } 
+4
source

If I understood correctly, you have List<Map<String, Object>> . To sort it, you will need to write Comparator . There you can compare each entry separately (error handling removed for nuptiality):

 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); } } 
+2
source

All Articles