Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort a HashMap's entries by comparing values, where each value is an int[]?

I have a HashMap defined as HashMap<String, int[]>. The value is an int[] that will have exactly 2 numbers in it. What I want to do is sort this HashMap's entries by the sum of these 2 numbers.

Here is what I have. I am using Java 8. I just need to add the part where I sum the 2 ints in the int[] and treat it as one number then sort as I do below, but I am not sure how to add that part in.

hm.entrySet().stream()
    .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
like image 513
Teodorico Levoff Avatar asked Oct 19 '25 21:10

Teodorico Levoff


2 Answers

Here is a solution with Java 8 Comparator lambdas:

map.entrySet().stream()
              .sorted(Map.Entry.comparingByValue(
                      (v1, v2) -> v2[0] + v2[1] - v1[0] - v1[1]));

Note that this solution has a risk of overflowing/underflowing, see leeyuiwah answer for a better solution to that. The idea is to use comparingLong method instead.

like image 170
Hesham Attia Avatar answered Oct 21 '25 10:10

Hesham Attia


I am pretty sure that you can't create ordering element with HashMap. My suggestion is to use 2 other Map:

Map<Integer,String> tempMap = new TreeMap<Integer,String>();
Map<String,int []> resultMap = new LinkedHashMap<String,int[]>();

First you need to copy your hm map into tempMap, the natural ordering in TreeMap will order your integer key in ascending order.

After you get the sorted result in tempMap, you can copy into resultMap to get the final result.

"Copy" means you iterate your old map then put the (key,value) in the new map.

This approach will cost you double memory, but it will run with the complexity O(n lg n).

If you want to use Comparator, you can use this approach:

hm.entrySet().stream().sorted(Map.Entry.comparingByValue(
    new Comparator<int []>() {
    public int compare(int [] a,int [] b) {
        int sumA = a[0] + a[1];
        int sumB = b[0] + b[1];
        return sumA - sumB;
    }
}));
like image 30
algojava Avatar answered Oct 21 '25 10:10

algojava