1

I have a list of HashMap and I want to sort it in ascending order in Java.

I am using custom Comparator to implement the logic, but its failing. Its just grouping the list based on Map keys. Its not sorting the list entirely.

My Code looks like-

public class ListMap {

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        List<HashMap<String, String>> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            int value = randInt(1, 20);
            long timeInMillis = cal.getTimeInMillis();
            HashMap<String, String> mp = new HashMap<>();
            mp.put("" + value, "Values" + value + ":" + timeInMillis);
            list.add(mp);
        }

        Collections.sort(list, new Comparator<Map<String, String>>() {
            @Override
            public int compare(Map<String, String> map1,
                    Map<String, String> map2) {
                String val1 = "";
                String val2 = "";
                for (Map.Entry<String, String> entry : map1.entrySet()) {
                    val1 = entry.getKey();
                }
                for (Map.Entry<String, String> entry : map2.entrySet()) {
                    val2 = entry.getKey();
                }
                return val1.compareTo(val2);
            }
        });

        for (Map<String, String> hashMap : list) {
            for (Map.Entry<String, String> entry : hashMap.entrySet()) {
                System.out.println(entry.getKey() + "/" + entry.getValue());
            }
        }

    }

    public static int randInt(int min, int max) {
        Random rand = new Random();
        int randomNum = rand.nextInt((max - min) + 1) + min;

        return randomNum;
    }

}

It prints the output-

10/Values10:1437660285301
11/Values11:1437660285301
11/Values11:1437660285301
11/Values11:1437660285301
13/Values13:1437660285301
13/Values13:1437660285301
15/Values15:1437660285301
15/Values15:1437660285301
15/Values15:1437660285301
16/Values16:1437660285301
17/Values17:1437660285301
18/Values18:1437660285301
18/Values18:1437660285301
19/Values19:1437660285301
19/Values19:1437660285301
2/Values2:1437660285301
3/Values3:1437660285301
4/Values4:1437660285301
6/Values6:1437660285301
6/Values6:1437660285301

It groups the values by key, but I want the entire sorted list like in the above example.

I was expecting 2 and then 3, then 4 and go on.

2
  • Do you know about lexicographic ordering of Strings and "10" comes before "2"? If you search a bit and learn this you will solve your problem easily. Commented Jul 23, 2015 at 14:12
  • Try changing val1.compareTo(val2); to Integer.parseInt(val1).compareTo(Integer.parseInt(val2)); Commented Jul 23, 2015 at 14:14

2 Answers 2

4

You're comparing based on the keys which are of type String. Comparison will be done lexicographically, i.e. 12 is less than 2.

You need to compare the keys as Integers in the comparator:

Collections.sort(list, new Comparator<Map<String, String>>() {
    @Override
    public int compare(Map<String, String> map1,
             Map<String, String> map2) {
        String val1 = "";
        String val2 = "";
        for (Map.Entry<String, String> entry : map1.entrySet()) {
            val1 = entry.getKey();
        }
        for (Map.Entry<String, String> entry : map2.entrySet()) {
            val2 = entry.getKey();
        }

        return Integer.valueOf(val1).compareTo(Integer.valueOf(val2));
    }
});
Sign up to request clarification or add additional context in comments.

Comments

0

Just modify your comparator converting the key string to an integer:

new Comparator<Map<String, String>>() {
     @Override
     public int compare(Map<String, String> map1,
             Map<String, String> map2) {
        String val1 = "";
        String val2 = "";
        for (Map.Entry<String, String> entry : map1.entrySet()) {
             val1 = entry.getKey();
        }
        for (Map.Entry<String, String> entry : map2.entrySet()) {
             val2 = entry.getKey();
        }

        int key1 = Integer.parseInt(val1);
        int key2 = Integer.parseInt(val2);
        return key1.compareTo(key2);
     }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.