Java 为什么 HashMap 的 toString 函数以不同的顺序打印自己?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18778410/
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
Why does toString function of a HashMap prints itself with a different order?
提问by unmultimedio
I have this very simple piece of code, and I was just trying to play a bit with different kind of objects inside a Map.
我有一段非常简单的代码,我只是想在 Map 中使用不同类型的对象。
//There's a bit of spanish, sorry about that
//just think 'persona1' as an object with
//a string and an int
Map mapa = new HashMap();
mapa.put('c', 12850);
mapa.put(38.6, 386540);
mapa.put("Andrés", 238761);
mapa.put(14, "Valor de 14");
mapa.put("p1", persona1);
mapa.put("Andrea", 34500);
System.out.println(mapa.toString());
And then I expect from console something like:
然后我希望从控制台得到类似的东西:
{c=12850, 38.6=386540, Andrés=238761, 14=Valor de 14, p1={nombre: Andres Perea, edad: 10}, Andrea=34500}
But susprisingly for me I got same data in different order:
但令我惊讶的是,我以不同的顺序获得了相同的数据:
{38.6=386540, Andrés=238761, c=12850, p1={nombre: Andres Perea, edad: 10}, Andrea=34500, 14=Valor de 14}
It doesn't matter if I try other kind of objects, even just Strings or numeric types, it always does the same, it makes a different without-apparently-any-sense order.
如果我尝试其他类型的对象,即使只是字符串或数字类型,也没关系,它总是做同样的事情,它会产生不同的、显然没有任何意义的顺序。
Can someone give me a hint why this happens? Or may be something too obvious I'm missing?
有人可以给我一个提示为什么会发生这种情况吗?或者可能是我遗漏的太明显的东西?
I'm using Java 1.7 and Eclipse Juno.
我正在使用 Java 1.7 和 Eclipse Juno。
采纳答案by Vimal Bera
As per Oracle's documentation
根据 Oracle 的文档
The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls. This 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.
HashMap 类大致等同于 Hashtable,不同之处在于它是不同步的并且允许空值。此类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
Refer to HashMapJavaDocs.
请参阅HashMapJavaDocs。
回答by upog
Maps does not maintain the order the order in which elements were added, List will maintain the order of elements
Maps 不维护添加元素的顺序,List 会维护元素的顺序
"The order of a map is defined as the order in which the iterators on the map's collection views return their elements. Some map implementations, like the TreeMap class, make specific guarantees as to their order; others, like the HashMap class, do not."
“地图的顺序被定义为地图集合视图上的迭代器返回其元素的顺序。一些地图实现,如 TreeMap 类,对它们的顺序做出特定保证;其他的,如 HashMap 类,则没有.”
回答by Ruchira Gayan Ranaweera
HashMapnot guaranteed the order of element. If you want to keep order use LinkedHashMap.
HashMap不保证元素的顺序。如果您想保持顺序,请使用LinkedHashMap。
See following case
看下面的案例
Map<Integer,String> unOrderedMap=new HashMap<>();
unOrderedMap.put(1,"a");
unOrderedMap.put(3,"a");
unOrderedMap.put(2,"a");
System.out.println("HashMap output: "+unOrderedMap.toString());
Map<Integer,String> orderedMap=new LinkedHashMap<>();
orderedMap.put(1,"a");
orderedMap.put(3,"a");
orderedMap.put(2,"a");
System.out.println("LinkedHashMap output: "+orderedMap.toString());
Output:
输出:
HashMap output: {1=a, 2=a, 3=a}
LinkedHashMap output: {1=a, 3=a, 2=a}
回答by TheGraduateGuy
There are 3 class which implements map interface in java. 1. hashMap: Id does not guarantee any order. 2. Linked HashMap:It will store them in insertion order. 3. TreeMap: It will store in ascending order.(ASCII value)
java中有3个类实现了map接口。1. hashMap:Id 不保证任何顺序。2. Linked HashMap:它将按照插入顺序存储它们。3. TreeMap:按升序存储。(ASCII值)
So As per your requirement you can use Linked HashMap instead of HashMap.so instead of writing
因此,根据您的要求,您可以使用 Linked HashMap 而不是 HashMap.so 而不是编写
Map mapa = new HashMap();
create object of Linked HashMap
创建 Linked HashMap 的对象
Map mapa = new LinkedHashMap();
follow below link for more info.
请按照以下链接了解更多信息。
http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html
http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html
回答by VictorCreator
This is how a hashmap works: (citing from another source)
这就是哈希图的工作原理:(从另一个来源引用)
It has a number of "buckets" which it uses to store key-value pairs in. Each bucket has a unique number - that's what identifies the bucket. When you put a key-value pair into the map, the hashmap will look at the hash code of the key, and store the pair in the bucket of which the identifier is the hash code of the key. For example: The hash code of the key is 235 -> the pair is stored in bucket number 235. (Note that one bucket can store more then one key-value pair).
它有许多用于存储键值对的“存储桶”。每个存储桶都有一个唯一的编号——这就是标识存储桶的原因。当您将键值对放入映射中时,哈希映射会查看键的哈希码,并将该对存储在标识符为键的哈希码的桶中。例如:key的hash码是235->这对存储在桶号235中。(注意一个桶可以存储多个key-value对)。
When you lookup a value in the hashmap, by giving it a key, it will first look at the hash code of the key that you gave. The hashmap will then look into the corresponding bucket, and then it will compare the key that you gave with the keys of all pairs in the bucket, by comparing them with equals().
当你在 hashmap 中查找一个值时,通过给它一个键,它会首先查看你给的键的哈希码。然后 hashmap 将查看相应的存储桶,然后将您提供的键与存储桶中所有对的键进行比较,将它们与 equals() 进行比较。
Now you can see how this is very efficient for looking up key-value pairs in a map: by the hash code of the key the hashmap immediately knows in which bucket to look, so that it only has to test against what's in that bucket.
现在您可以看到这对于在映射中查找键值对非常有效:通过键的哈希码,哈希映射立即知道要查找哪个桶,因此它只需要针对该桶中的内容进行测试。
Looking at the above mechanism, you can also see what requirements are necessary on the hashCode()
and equals()
methods of keys:
看上面的机制,也可以看出对keyshashCode()
和equals()
methods有什么要求:
If two keys are the same (equals() returns true when you compare them), their hashCode() method must return the same number. If keys violate this, then keys that are equal might be stored in different buckets, and the hashmap would not be able to find key-value pairs (because it's going to look in the same bucket).
If two keys are different, then it doesn't matter if their hash codes are the same or not. They will be stored in the same bucket if their hash codes are the same, and in this case, the hashmap will use equals() to tell them apart.
如果两个键相同(当您比较它们时,equals() 返回 true),则它们的 hashCode() 方法必须返回相同的数字。如果键违反了这一点,那么相等的键可能会存储在不同的存储桶中,并且哈希图将无法找到键值对(因为它会在同一个存储桶中查找)。
如果两个键不同,那么它们的哈希码是否相同并不重要。如果它们的哈希码相同,它们将存储在同一个桶中,在这种情况下,哈希图将使用 equals() 来区分它们。
Now, when you put all your "key-value" pairs in the hashmap, and print them, it prints them in some random order of the keys which got generated by hashing the value yousupplied for keys.
现在,当您将所有“键值”对放入哈希映射并打印它们时,它会以通过散列您为键提供的值生成的键的某种随机顺序打印它们。
If your requirement is stillto maintain the ordering, you can use the LinkedHashMap
in Java.
如果您的要求仍然是保持顺序,则可以使用LinkedHashMap
Java 中的 。
Hope this helps :-)
希望这可以帮助 :-)
Edit: Original Post: How does a Java HashMap handle different objects with the same hash code?