Java 从 HashMap 中检索到的值的顺序是插入顺序吗
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2144776/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is the order of values retrieved from a HashMap the insertion order
提问by javagurl
I am trying figure out the order in which the values in a HashMap are/can be retrieved. Heres the code snippet for the same.
我正在尝试找出 HashMap 中的值被/可以被检索的顺序。这是相同的代码片段。
import java.util.HashMap;
public class HashMapExample {
public static void main(String[] args) {
HashMap<Integer, String> hashmap = new HashMap<Integer, String>();
hashmap.put(1, "apple" );
hashmap.put(2, "lemon" );
hashmap.put(3, "orange" );
hashmap.put(4, "banana" );
hashmap.put(5, "litchi" );
hashmap.put(6, "mango" );
hashmap.put(7, "papaya" );
System.out.println(hashmap.size());
for (String key : hashmap.values()) {
System.out.println(key);
}
}
}
output:
输出:
7
apple
lemon
orange
banana
litchi
mango
papaya
The values are printed in the order in which they have been inserted. Is this true in general? I was expecting the values to be printed in an arbitrary order. This is using Java 6.
这些值按它们插入的顺序打印。这是真的吗?我期待以任意顺序打印值。这是使用Java 6。
采纳答案by Stephen C
The values are printed in the order in which they have been inserted. Is this true in general? I was expecting the values to be printed in random order.
这些值按它们插入的顺序打印。这是真的吗?我期待以随机顺序打印这些值。
The HashMap
API does not define the order of iteration.
该HashMap
API没有定义迭代的顺序。
However, if you look at the implementation of HashMap, you can deduce that there is a complex transient relationship between the iteration order, the keys' hash values, the order in which the keys were inserted and the size of the hashtable. This relationship gets scrambled if the hashtable resizes itself.
但是,如果您查看 HashMap 的实现,您可以推断出迭代顺序、键的哈希值、键的插入顺序和哈希表的大小之间存在复杂的瞬态关系。如果哈希表调整自身大小,这种关系就会被打乱。
In your case, you are using Integer
keys which means that the hash values of the keys are the key values themselves. Also, you inserted the entries in key order. This leads (fortuitously!) to the iteration order matching the insertion order. But if you kept inserting more keys, you would find that the iteration order "wraps around". Then as the table goes through a series of resizes, the order will get progressively more and more scrambled.
在您的情况下,您使用的是Integer
键,这意味着键的哈希值就是键值本身。此外,您按键顺序插入了条目。这导致(偶然!)迭代顺序与插入顺序匹配。但是如果你不断插入更多的键,你会发现迭代顺序“环绕”。然后,随着表格经过一系列调整大小,订单将逐渐变得越来越混乱。
In short, what you are seeing is an artefact of the hashtable implementation, and not something that you can (or should) sensibly make use of. Not least because it couldchange from one Java release to the next.
简而言之,您所看到的是哈希表实现的人工制品,而不是您可以(或应该)明智地利用的东西。尤其是因为它可以从一个 Java 版本更改为下一个版本。
回答by notnoop
From the Javadoc: HashMap
"class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time."
来自 Javadoc:HashMap
“类不保证地图的顺序;特别是,它不保证顺序会随着时间的推移保持不变。”
If you need consistent ordering, you can use LinkedHashMap
(for insertion/access order), or TreeMap
(for comparision order). Please note, that these maintain the order of the keys, not the values.
如果您需要一致的排序,您可以使用LinkedHashMap
(用于插入/访问顺序)或TreeMap
(用于比较顺序)。请注意,这些保持键的顺序,而不是值。
回答by MadMurf
Try LinkedHashMap if order is important... see from JavaDoc
如果顺序很重要,请尝试 LinkedHashMap...参见 JavaDoc
public class LinkedHashMap extends HashMap
Hash table and linked list implementation of the Map interface, with predictable iteration order. This implementation differs from HashMap in that it maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map. (A key k is reinserted into a map m if m.put(k, v) is invoked when m.containsKey(k) would return true immediately prior to the invocation.)
公共类 LinkedHashMap 扩展了 HashMap
Map接口的哈希表和链表实现,迭代顺序可预测。此实现与 HashMap 的不同之处在于它维护一个双向链表,贯穿其所有条目。这个链表定义了迭代顺序,这通常是键被插入到映射中的顺序(插入顺序)。请注意,如果将键重新插入映射中,则插入顺序不会受到影响。(如果当 m.containsKey(k) 在调用之前立即返回 true 时调用了 m.put(k, v),则键 k 被重新插入到映射 m 中。)
回答by Rog
A LinkedHashMapis what you're after. From the doco, it differs from HashMap in that it maintains a doubly-linked list running through all of its entries
一个LinkedHashMap的是你追求的。从 doco 来看,它与 HashMap 的不同之处在于它维护一个双向链表,贯穿其所有条目
回答by Jim Ferrans
A related collection is java.util.concurrent's ConcurrentSkipListMap. A skiplistallows you to traverse the entries in key order and also look them in random order (but not as fast as a HashMap).
一个相关的集合是 java.util.concurrent 的ConcurrentSkipListMap。一个skiplist允许您遍历在关键秩序的条目,并以随机顺序看他们(但速度不如一个HashMap)。
There's a nice skiplist demo applet.
有一个很好的跳过列表演示小程序。
回答by Dewansh Nigam
No, the order is not preserved in case of HashMap (if you want sorted implementation.) In case you want keys to be sorted, you can use TreeMap.
不,在 HashMap 的情况下不保留顺序(如果您想要排序实现。)如果您想要对键进行排序,您可以使用 TreeMap。
for example - {[3=1],[2=50],[20=4],[14=1]} -> HashMap
例如 - {[3=1],[2=50],[20=4],[14=1]} -> HashMap
for TreeMap, you get - {[2=50],[3=1],[14=1],[20=4]} -> TreeMap
对于 TreeMap,你得到 - {[2=50],[3=1],[14=1],[20=4]} -> TreeMap