【问题标题】:Why LinkedHashMap can't sort HashMap while TreeMap can?为什么 LinkedHashMap 不能排序 HashMap 而 TreeMap 可以?
【发布时间】:2019-02-16 16:58:13
【问题描述】:

我正在尝试使用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() + "    ");
        }

输出:
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 对这个问题免疫?
谢谢

【问题讨论】:

  • 是什么让您觉得LinkedHashMap 可以排序任何东西?
  • @SotiriosDelimanolis 它按插入顺序排序。
  • 你得到了插入顺序作为输出。
  • @LuCio。不它不是。广告订单是10,20,30,40。输出为20,40,10,30。请看第二个例子
  • @pippilongstocking 这是 HashMap 的插入顺序。不是 LinkedHashMap 的插入顺序。您将 HashMap 传递给 LinkedHashMap 构造函数。因此,此构造函数遍历 HashMap(没有排序),并将 HashMap 的每个元素插入到 LinkedHashMap 中。如您所见,您得到的顺序与 HashMap 中的顺序相同,这表明保留了插入顺序。

标签: java collections hashmap treemap linkedhashmap


【解决方案1】:

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

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

另一方面,TreeMap 保持键排序,因此您将键放入 TreeMap 中的顺序(在您的示例中,这取决于在遍历源 @ 时遇到键的顺序) 987654330@) 无关紧要 - 生成的 Map 将始终被排序。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      LinkedHashMap 的 JavaDoc 说:

      这个链表定义了迭代顺序,通常是 将键插入映射的顺序(插入顺序)。

      通过插入HashMap 创建LinkedHashMapLinkedHashMap 保留HashMap hMap 的顺序。

      HashMap 的 JavaDoc 说:

      这个类不保证地图的顺序;在 特别是,

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

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

      关于LinkedHashMap,它不会自行排序。


      延伸阅读:Sorting LinkedHashMap

      【讨论】:

        【解决方案4】:

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

        2) Linkedhasmap 会像列表一样维护插入顺序。

        【讨论】:

          【解决方案5】:

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

          LinkedHashMap 的“排序”意思不是按键值比较排序。相反,它表示插入顺序或访问顺序。

          插入顺序 , ,

          迭代顺序为插入顺序:, ,

          那么假设实现access(get/put)操作 将顺序迭代为访问顺序:, ,

          【讨论】:

            猜你喜欢
            • 2012-05-13
            • 2011-02-22
            • 2013-08-12
            • 1970-01-01
            • 2019-07-23
            • 1970-01-01
            • 2014-12-24
            • 1970-01-01
            • 2013-07-28
            相关资源
            最近更新 更多