Search code examples
javacollectionshashmaptreemaplinkedhashmap

Why LinkedHashMap can't sort HashMap while TreeMap can?


I'm trying to sort HashMap's output using LinkedHashMapand TreeMap.

When I use TreeMap to sort out HashMap it works like a charm.

        Map<Integer, String> hMap = new HashMap<Integer, String>();

        hMap.put(40, "d");
        hMap.put(10, "a");
        hMap.put(30, "c");
        hMap.put(20, "b");

        System.out.println(" ");
        System.out.println("before");

        for (Map.Entry m1 : hMap.entrySet()) {
            System.out.print(m1.getKey() + " " + m1.getValue() + "    ");
        }

        System.out.println("after");

        Map<Integer, String> hTree = new TreeMap<Integer, String>(hMap);
        for (Map.Entry m2 : hTree.entrySet()) {
            System.out.print(m2.getKey() + " " + m2.getValue() + "    ");
        }

Output :
before 20 b 40 d 10 a 30 c
after 10 a 20 b 30 c 40 d

But when I try with LinkedHashMap to sort HashMap it doesn't seems to work.

        Map<Integer, String> hMap = new HashMap<Integer, String>();

        hMap.put(10, "a");
        hMap.put(20, "b");
        hMap.put(30, "c");
        hMap.put(40, "d");

        System.out.println("before");

        for (Map.Entry m1 : hMap.entrySet()) {
            System.out.print(m1.getKey() + " " + m1.getValue() + "    ");
        }
        System.out.println(" ");
        System.out.println("after");

        LinkedHashMap<Integer, String> lhMap = new LinkedHashMap<Integer, String>(hMap);

        Iterator it = lhMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry me = (Map.Entry) it.next();
            System.out.print(me.getKey() + " " + me.getValue()+"   ");
        }

Output :

before
20 b    40 d    10 a    30 c     
after
20 b   40 d   10 a   30 c  

Can anyone tell me why is this sorting doesn't work? Is that becuase LinkedHashMap is filtering the HashMap?
If it is why TreeMap is immune to that issue?
Thank you


Solution

  • LinkedHashMap maintains the insertion order. This means that if you pass to the constructor a sorted Map, or put the keys in the LinkedHashMap in sorted order, it will remain sorted.

    However, you pass a HashMap to the LinkedHashMap constructor, and it's not sorted (since HashMap has no ordering). Therefore the resulting LinkedHashMap is also not ordered.

    On the other hand, TreeMap keeps the keys sorted, so the order in which you put the keys in the TreeMap (which in your example is determined by the order the keys are encountered while iterating over the source HashMap) doesn't matter - the resulting Map will always be sorted.