为什么HashMap的toString函数用不同的顺序打印自己?

时间:2013-09-13 04:38:56

标签: java hashmap tostring

我有一段非常简单的代码,我只想尝试在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());

然后我希望从控制台中得到类似的东西:

{c=12850, 38.6=386540, Andrés=238761, 14=Valor de 14, p1={nombre: Andres Perea, edad: 10}, Andrea=34500}

但令我惊讶的是,我得到了不同顺序的相同数据:

{38.6=386540, Andrés=238761, c=12850, p1={nombre: Andres Perea, edad: 10}, Andrea=34500, 14=Valor de 14}

如果我尝试其他类型的对象并不重要,即使只是字符串或数字类型,它总是一样,它会产生一种不同的,没有任何明显的任何意义顺序。

有人能给我一个提示,为什么会这样?或者可能是一个太明显我错过的东西?

我正在使用Java 1.7和Eclipse Juno。

5 个答案:

答案 0 :(得分:17)

根据Oracle的文档

  

HashMap类大致相当于Hashtable,除了它是不同步的并且允许空值。这个类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。

请参阅HashMap JavaDocs。

答案 1 :(得分:15)

在java中有3个实现map接口的类。 1. hashMap:Id不保证任何订单。 2.链接的HashMap:它将按插入顺序存储它们。 3. TreeMap:它将按升序存储。(ASCII值)

因此,根据您的要求,您可以使用Linked HashMap而不是HashMap.so而不是编写

Map mapa = new HashMap();

创建Linked HashMap的对象

Map mapa = new LinkedHashMap();

按照以下链接获取更多信息。

http://docs.oracle.com/javase/tutorial/collections/interfaces/map.html

答案 2 :(得分:3)

HashMap无法保证元素的顺序。如果您想保持订单使用LinkedHashMap

见以下案例

    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());

输出:

   HashMap output: {1=a, 2=a, 3=a}
   LinkedHashMap output: {1=a, 3=a, 2=a}

答案 3 :(得分:1)

地图不按顺序维护添加元素的顺序,List将维护元素的顺序

“映射的顺序定义为地图集合视图上的迭代器返回其元素的顺序。一些映射实现(如TreeMap类)对其顺序进行了特定保证;其他映射实现(如HashMap类) ,不要。“

答案 4 :(得分:0)

这是散列图的工作方式:(引用其他来源)


它有许多用于存储键值对的“桶”。每个桶都有一个唯一的编号 - 这就是识别存储桶的内容。将键值对放入映射时,哈希映射将查看键的哈希码,并将该对存储在桶中,其中标识符是键的哈希码。例如:密钥的哈希码是235 - &gt;该对存储在桶号235中。(注意,一个桶可以存储多个键值对)。

当你在hashmap中查找一个值时,通过给它一个键,它将首先查看你给出的键的哈希码。然后,hashmap将查看相应的存储桶,然后通过将它们与equals()进行比较,将它与您提供的密钥与存储桶中所有对的密钥进行比较。

现在你可以看到这对于在地图中查找键值对非常有效:通过键盘的哈希码,哈希表可以立即知道要查看哪个桶,这样它只需要测试中的内容。那桶。

查看上述机制,您还可以了解密钥的hashCode()equals()方法需要哪些要求:

  • 如果两个键相同(equals()在比较它们时返回true),则它们的hashCode()方法必须返回相同的数字。如果密钥违反了这个,那么相同的密钥可能会存储在不同的存储桶中,并且hashmap将无法找到键值对(因为它将在同一个存储桶中查找)。

  • 如果两个密钥不同,那么它们的哈希码是否相同并不重要。如果它们的哈希码相同,它们将存储在同一个桶中,在这种情况下,hashmap将使用equals()来区分它们。


现在,当您将所有“键值”对放在哈希映射中并打印它们时,它会以密钥的​​随机顺序打印它们,这些键是通过哈希值提供的。对于钥匙。

如果您的要求以维持排序,则可以使用Java中的LinkedHashMap

希望这会有所帮助: - )

修改:原帖:How does a Java HashMap handle different objects with the same hash code?