Hello guys i have a hash map like a:1,c:2,d:3,b:2 and i want to sort it like d:3,b:2,c:2,a:1, descending in values and alphabetical order in keys how can i do it i would be grateful for any help thanks!
-
Can you demonstrate *any* effort at solving this yourself? – Scott Hunter Apr 09 '21 at 23:52
-
Hey Dante, welcome ! Have you tried something already? It would be nice to start with something existing to help you further – Yassin Hajaj Apr 09 '21 at 23:52
-
I reopened because the supposed duplicate is about simple sorting of a map. This question is more complex, asking to sort first by values and then by keys. – Basil Bourque Apr 10 '21 at 08:03
3 Answers
Sort the following in descending order of values then keys. I amended the list to make it more interesting.
Map<String, Integer> map = Map.of("a", 8, "b", 2, "c", 4, "d",
8, "e", 3, "f", 4, "g", 7, "h", 1, "i", 5, "j", 2);
First define a Comparator
to use in sorting the Map entries. Each entry is represented by the Map.Entry
class. That class offers methods comparingByValue()
and comparingByKey()
.
The following code says, first sort by value
, then by the key
. These are sorted in natural order except the following reversed()
method says reverse the sorting of all comparators prior. So the values
will be sorted in reversed order and the keys
in alphabetical order.
Comparator<Entry<String, Integer>> comp = Entry
.<String, Integer>comparingByValue().reversed()
.thenComparing(Entry.comparingByKey());
This streams the existing map's entrys and applies the comparator to the sort method. It then collects them in a linked hashMap to preserve the order. The merge function does not play a part in this but is syntactically required.
Map<String, Integer> lhmap =
map.entrySet().stream().sorted(comp)
.collect(Collectors.toMap(Entry::getKey,
Entry::getValue,
(a, b) -> a, // merge function
LinkedHashMap::new));
lhmap.entrySet().forEach(System.out::println);
That code prints:
a=8
d=8
g=7
i=5
c=4
f=4
e=3
b=2
j=2
h=1

- 36,363
- 4
- 24
- 39
-
I think you misread the Question, as I had done. The Question asks for sorting by *values* primarily, and sort by *keys* secondarily. The values may coincidentally be equal (be multiple), so sorting by keys secondarily does indeed make sense. – Basil Bourque Apr 10 '21 at 02:29
-
-
I have figured it out thanks to WJS with a comparator like `Comparator
> firstwithvaluessecoundwiththekeys = Map.Entry . – Dante Allegri Apr 10 '21 at 08:36comparingByValue().reversed() .thenComparing(Map.Entry.comparingByKey());` I have solved my question thanks everyone again!
A HashMap
is not necessarily ordered, and in fact does not guarantee that the key value pair orders wil lremain constant over time. From the docs:
Hash table based implementation of the Map interface. This implementation provides all of the optional map operations, and permits null values and the null key. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
If you want a sorted map, use a NavigableMap
or SortedMap
. There are a few options. TreeMap
is probably the simplest.
A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
So to create a map with the keys in descending alphabetical order something like this should do the tick:
Comparator<String> comparator = new Comparator<>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
};
TreeMap<String, Integer> treeMap = new TreeMap<>(comparator);

- 303,325
- 100
- 852
- 1,154

- 3,001
- 2
- 10
- 24
-
How does this address the Question? The Question asks about sorting by values first, and then by keys secondarily. – Basil Bourque Apr 10 '21 at 01:17
-
OP asks how to sort a `HashMap`, so I gave them a simple example of creating a sorted map. I read the "descending in values and alphabetical order in keys" section as a description of the map in part because sorting on keys, and then values does not make much sense given that keys in a `HashMap` are unique and sorting matching keys on value is a non-issue. That could be misinterpretation on my part. I appreciate you additions to my answer, they were definitely helpful! – joshmeranda Apr 10 '21 at 01:37
This answer is using java 8 streams.
//LinkedHashMap preserve the ordering of elements in which they are inserted
LinkedHashMap<String, Integer> reverseSortedMap = new LinkedHashMap<>();
unSortedMap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.forEachOrdered(x -> reverseSortedMap.put(x.getKey(), x.getValue()));
System.out.println("Reverse Sorted Map : " + reverseSortedMap);

- 83
- 1
- 4
- 14