我有一段非常简单的代码,我只想尝试在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。
答案 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?