为什么 LinkedHashMap 不能对 HashMap 进行排序而 TreeMap 可以?

Why LinkedHashMap can't sort HashMap while TreeMap can?

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

当我使用 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() + "    ");
        }

输出:
之前 20 b 40 d 10 a 30 c<br> 后 10 个 20 个 30 个 c 40 个

但是当我尝试使用 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 不受该问题影响的原因?
谢谢

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

但是,您将 HashMap 传递给 LinkedHashMap 构造函数,它没有排序(因为 HashMap 没有排序)。因此,结果 LinkedHashMap 也未排序。

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

TreeMap 按键实现的 compareTo 排序(或在构造时传递的比较器函数,比较键)。 LinkedHashMap 仅保留插入顺序,所以我猜当您使用哈希映射创建它时,插入顺序与迭代 HashMap 时的插入顺序相同。

LinkedHashMap 的 JavaDoc 说:

This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order).

通过插入 HashMap 创建 LinkedHashMapLinkedHashMap 保留 HashMap hMap.

的顺序

HashMap 的 JavaDoc 说:

This class makes no guarantees as to the order of the map; in particular,

因此 HashMap hMap 的未保证顺序由 LinkedHashMap lhMap 保留。

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

关于 LinkedHashMap 它不会自行排序。


进一步阅读:Sorting LinkedHashMap

1) Treemap默认按照自然顺序对元素进行排序。

2) Linkedhasmap会像list一样维护插入顺序

HashMap 不保留键的排序。更重要的是,请注意,当 HashMap 实例的大小因负载因素而发生变化时,它不会完全相同地显示 (k-v) 序列。

"sort" 表示LinkedHashMap 不是按键值比较排序。相反,它表示插入顺序或访问顺序。

插入订单 <2,"A">, <1,"B"> ,<3,"C">

迭代顺序作为插入顺序:<2,"A">, <1,"B"> ,<3,"C">

则假设实现accessing(get/put)<1,"B">操作 迭代顺序作为访问顺序:<2,"A">, <3,"C">,<1,"B">