为什么 LinkedHashMap 不能对 HashMap 进行排序而 TreeMap 可以?
Why LinkedHashMap can't sort HashMap while TreeMap can?
我正在尝试使用 LinkedHashMap
和 TreeMap
对 HashMap
的输出进行排序。
当我使用 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 个
但是当我尝试使用 LinkedHashMap
对 HashMap
进行排序时,它似乎不起作用。
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
创建 LinkedHashMap
,LinkedHashMap
保留 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">
我正在尝试使用 LinkedHashMap
和 TreeMap
对 HashMap
的输出进行排序。
当我使用 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 个
但是当我尝试使用 LinkedHashMap
对 HashMap
进行排序时,它似乎不起作用。
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
创建 LinkedHashMap
,LinkedHashMap
保留 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">