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.
source share