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
HashMap
s 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
Why Does Ssl Handshake Give 'Could Not Generate Dh Keypair' Exception
Why Does Writeobject Throw Java.Io.Notserializableexception and How to Fix It
Display Indeterminate Jprogressbar While Batch File Runs
How to Convert a Stack Trace to a String
Initialising a Multidimensional Array in Java
Accessing Members of Items in a JSONarray with Java
Eclipse Java Debugging: Source Not Found
Ignoring New Fields on JSON Objects Using Jackson
How to Play .Wav Files with Java
Why Are Local Variables Not Initialized in Java
Can You Recommend a Java Library for Reading (And Possibly Writing) CSV Files
Scale the Imageicon Automatically to Label Size
How to Maintain Jtable Cell Rendering After Cell Edit
Java 8 Iterable.Foreach() VS Foreach Loop
In Java, How to Convert a Byte Array to a String of Hex Digits While Keeping Leading Zeros