How to Sort a Hashmap in Java

How to sort a HashMap, values are integers. I want to sort from highest to lowest

You can use Comparator.comparingInt to sort in the correct order. Streams can be used to sort and collect the new Map to a LinkedHashMap to retain the new order.

Map<Player, Integer> result = eloMap.entrySet().stream()
.sorted(Comparator.comparingInt(Map.Entry::getValue))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
(a,b)->b, LinkedHashMap::new));

How to sort a hash map using key descending order

HashMaps don't support sorting. They store entries in buckets, how they see it fit, just based on the hashCode value of the keys. They are fine for storing things and looking them up afterwards, but unsuitable for iterating over their contents (which is what you apparently want to do) because you cannot rely on their order and iterating over it is usually expensive.

Try a TreeMap instead. You can specify a custom comparator that does just the reverse of the default comparator. In that case your entries will be ordered in descending order. Collections.reverseOrder will create such a comparator for you, you can use it like this:

new TreeMap<Integer, String>(Collections.reverseOrder());

sort a hashmap by the Integer Value desc

For inverse ordering switch o2 and o1. For getting the first element just access the array at index 0:

Map<String, Integer> map = new HashMap<>();
map.put("a", 4);
map.put("c", 6);
map.put("b", 2);
Object[] a = map.entrySet().toArray();
Arrays.sort(a, new Comparator() {
public int compare(Object o1, Object o2) {
return ((Map.Entry<String, Integer>) o1).getValue().compareTo(
((Map.Entry<String, Integer>) o2).getValue());
}
});
for (Object e : a) {
System.out.println(((Map.Entry<String, Integer>) e).getKey() + " : "
+ ((Map.Entry<String, Integer>) e).getValue());
}

System.out.println("first element is " + ((Map.Entry<String, Integer>) a[0]).getKey() + " : "
+ ((Map.Entry<String, Integer>) a[0]).getValue());

Which prints

b : 2

a : 4

c : 6

first element is b : 2

If you have access to lambda expression you can simplify the sorting using those:

Arrays.sort(a, (o1, o2) -> 
((Map.Entry<String, Integer>) o1).getValue().compareTo(((Map.Entry<String, Integer>) o2).getValue()));

How to sort the hashmap in descending order by values and if the values are the same then by key in ascending order

You can "chain" Comparators by adding calls to thenComparing:

Map<Integer, Integer> sortedRelevance = new LinkedHashMap<>();
relevance.entrySet()
.stream()
.sorted(Map.Entry.<Integer, Integer> comparingByValue(Comparator.reverseOrder())
.thenComparing(Map.Entry.comparingByKey()))
.forEachOrdered(x -> sortedRelevance.put(x.getKey(), x.getValue()));

How to sort HashMap of String and Integer, by value and in case of duplicate then sort them by key, Including Russian words

I would do something like this:

        List<String> sortedEntries = unsortMap.entrySet().stream()
.sorted(Comparator.comparingLong(Map.Entry<String, Integer>::getValue)
.reversed()
.thenComparing(Map.Entry::getKey)
)
.map(it -> it.getKey() + "-" + it.getValue())
.collect(Collectors.toList());

How to sort HashMap entries values by multiple properties Java8

You can use the following comparator for sorting:

Comparator
.comparingLong(UserMetrics::getParam1)
.thenComparingLong(UserMetrics::getParam2);

The difficulty is, however that you want to sort values, not keys. It seems also you need both keys and values. For this you could make and sort a copy of the entry set of your map. Something along the lines:

List<Map.Entry<String, UserMetrics>> sortedEntries = new ArrayList<>(map.entrySet());
Collections.sort(sortedEntries,
Map.Entry.comparingByValue(
Comparator
.comparingLong(UserMetrics::getParam1)
.thenComparingLong(UserMetrics::getParam2)));

Alternatively you can also use a sorted collection (like TreeSet) or a sorted stream - normally you can provide your own comparator to the "sorting things".

Also note that I'm using comparingLong/thenComparingLong, unlike other answers where people just used comparing/thenComparing. The problem with comparing/thenComparing is that if you have primitive types like long, comparing/thenComparing will essentially box them into wrapper types like Long, which is totally unnecessary.

Java sort a Hashmap on Value

You can create an List of Entry set from the map. Sort the List using Collections.sort(). You can pass the custom Comparator for sorting by Key when Value(s) are same.

Set<Entry<String, Integer>> set = map.entrySet();
List<Entry<String, Integer>> list = new ArrayList<Entry<String, Integer>>(set);
Collections.sort( list, new Comparator<Map.Entry<String, Integer>>()
{
public int compare( Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2 )
{
int result = (o2.getValue()).compareTo( o1.getValue() );
if (result != 0) {
return result;
} else {
return o1.getKey().compareTo(o2.getKey());
}
}
} );

Java 8 Sort HashMap where map key is an object of String, Integer

One way you can do it without using DiscountCounts class is, first sort the list and then perform the groping by operation, and use LinkedHashMap to save the sorted order

Map<List<Object>, Long> map = customerList.stream()
.sorted(Comparator.comparing(Customer::getName).thenComparing(Customer::getDiscount))
.collect(Collectors.groupingBy(x -> Arrays.asList(x.name, x.discount),LinkedHashMap::new, Collectors.counting()));

The another way using DiscountCounts class is, by override the equals and hashcode of DiscountCounts class and do a groupingBy creating DiscountCounts object for every Customer object as key in Map and use TreeMap with Comparator to sort the result

Map<DiscountCounts, Long> result = customerList.stream().collect(Collectors.groupingBy(
c -> new DiscountCounts(c.getName(), c.getDiscount()),
() -> new TreeMap<DiscountCounts, Long>(
Comparator.comparing(DiscountCounts::getName).thenComparing(DiscountCounts::getDiscount)),
Collectors.counting()));

@Andreas suggest in the comment enlighten me another way of doing it, and i feel this is one of the best approach you can implement Comparable on DiscountCounts and provide the sorting logic so that you don't need to provide Comparator to TreeMap

@Override
public int compareTo(DiscountCounts cust) {

int last = this.getName().compareTo(cust.getName());

return last == 0 ? this.getDiscount().compareTo(cust.getDiscount()) : last;
}

Map<DiscountCounts, Long> result1 = customerList.stream().collect(Collectors.groupingBy(
c -> new DiscountCounts(c.getName(), c.getDiscount()), TreeMap::new, Collectors.counting()));


Related Topics



Leave a reply



Submit