为什么LinkedHashMap无法对HashMap进行排序,而TreeMap却可以呢?

时间:2018-09-12 06:17:44

标签: java collections hashmap treemap linkedhashmap

我正在尝试使用HashMapLinkedHashMapTreeMap的输出进行排序。

当我使用TreeMap来整理HashMap时,它就像是一种魅力。

        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() + "    ");
        }

输出:
before 20 b 40 d 10 a 30 c
after 10 a 20 b 30 c 40 d

但是当我尝试使用LinkedHashMapHashMap进行排序时,它似乎不起作用。

        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()+"   ");
        }

输出:

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

谁能告诉我为什么这种排序不起作用?是因为LinkedHashMap正在过滤HashMap吗?
是否就是为什么TreeMap不受该问题困扰?
谢谢

4 个答案:

答案 0 :(得分:7)

LinkedHashMap保持插入顺序。这意味着,如果您将经过排序的Map传递给构造函数,或者按排序顺序将键放在LinkedHashMap中,它将保持排序状态。

但是,您将HashMap传递给LinkedHashMap构造函数,并且它没有排序(因为HashMap没有排序)。因此,生成的LinkedHashMap也没有排序。

另一方面,TreeMap保持键的排序,因此将键放入TreeMap的顺序(在您的示例中,由迭代时遇到键的顺序确定源HashMap上的内容无关紧要-结果Map将始终进行排序。

答案 1 :(得分:6)

LinkedHashMap的JavaDoc说:

  

此链表定义了迭代顺序,通常是   键插入地图的顺序(插入顺序)。

通过插入LinkedHashMap创建HashMapLinkedHashMap保留了HashMap hMap的顺序。

HashMap的JavaDoc说:

  

此类不保证地图的顺序;在   

因此HashMap hMap保留了LinkedHashMap lhMap的不确定顺序。

另一方面,您使用default constructor创建了TreeMap hTree。这意味着您使用其键的自然顺序创建了“ 新的空树形图。”。因此,hTree在每次插入时都进行排序。插入表示排序。

关于LinkedHashMap,它本身并没有排序。


进一步阅读:Sorting LinkedHashMap

答案 2 :(得分:5)

1)默认情况下,树形图将使用自然顺序对元素进行排序。

2)Linkedhasmap将保持列表等插入顺序。

答案 3 :(得分:0)

HashMap不会保留键的排序。此外,请注意,当HashMap实例的大小由于加载因子而变化时,它并不能完全显示(k-v)序列。

LinkedHashMap的“排序”表示与键值比较排序无关。相反,它表示插入顺序或访问顺序。

插入顺序<2,“ A”>,<1,“ B”>,<3,“ C”>

将插入订单重复:<2,“ A”>,<1,“ B”>,<3,“ C”>

然后假定实现访问(get / put)<1,“ B”>的操作 迭代顺序作为访问顺序:<2,“ A”>,<3,“ C”>,<1,“ B”>