For that you need to define a Comparator.
You can utilize for that purpose static methods that were added as an enhancement of Java 8 to the Comparator and Map.Entry interfaces.
Both methods comparingByValue() and comparingByKey() of the Map.Entry interface will generate a comparator for values and keys respectively. In order to obtain a descending order reversed() method needs to be applied on them.
Both comparators are chained together with the thenComparing() method.
Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
Map.Entry.<String, Integer>comparingByValue().reversed()
.thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());
Note that compiler is unable to infer the correct types of the arguments of comparingByValue() and comparingByKey() based only on the resulting type of the comparator.
Therefore, both comparingByValue() and comparingByKey()need to be provided with the generic type information explicitly <String, Integer> (types of keys and values respectively).
If it seems too tough to comprehend at first, you might split it into separate lines (in this case, type inference works fine):
Comparator<Map.Entry<String, Integer>> byValDesc =
Map.Entry.comparingByValue().reversed();
Comparator<Map.Entry<String, Integer>> byKeyDesc =
Map.Entry.comparingByKey().reversed();
Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
byValDesc.thenComparing(byKeyDesc);
for more information on how to build comparators with Java 8 methods, take a look at this tutorial
The next step is to create a sorted list of entries.
For that, you can either create a List of entries manually by passing an entry set to the constructor and then apply the method sort() on it, or by making use of the Stream API
In order to implement it with streams, first, we need to obtain a stream of entries. Apply sorting() operation by passing the given comparator and collect the result into a list by applying the terminal operation collect().
public static List<Map.Entry<String, Integer>> getMapEntryList(Map<String,Integer> data,
Comparator<Map.Entry<String, Integer>> comparator) {
return data.entrySet().stream()
.sorted(comparator)
.collect(Collectors.toList());
}
main()
public static void main(String[] args) {
Map<String,Integer> data = Map.of("a",10, "b",3,"c",10);
Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
Map.Entry.<String, Integer>comparingByValue().reversed()
.thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());
List<Map.Entry<String, Integer>> result = getMapEntryList(data, valDescThenKeyDesc);
System.out.println(result);
}
Output
[c=10, a=10, b=3]