我想知道Java如何在添加Map
(HashMap
或Hashtable
)时订购商品。密钥是由哈希码,内存引用还是按分配优先级排序的??
这是因为我注意到Map
中的同一对并不总是在同一个顺序
答案 0 :(得分:119)
java.util.HashMap
无序;你不能也不应该假设任何事情。
此课程不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
java.util.LinkedHashMap
使用了insert-order。
此实现与
HashMap
的不同之处在于它维护了一个贯穿其所有条目的双向链表。此链接列表定义迭代排序,通常是键插入映射的顺序(插入顺序)。
java.util.TreeMap
,SortedMap
,使用自然或自定义键排序。
地图根据其键的自然顺序排序,或者根据地图创建时提供的
Comparator
进行排序,具体取决于使用的构造函数。
答案 1 :(得分:17)
首先:HashMap
具体不提供稳定和/或定义的排序。因此,您观察到的任何内容都只是一个实现细节,您绝不能以任何方式依赖它。
因为知道看似随机排序的原因有时很有用,所以这是基本的想法:
HashMap
有多个存储条目(以数组形式实现),用于存储条目。
将项目添加到地图时,会根据其hashCode
的值和HashMap
的存储区大小将其分配给存储桶。 (请注意,存储桶可能已被占用,这称为冲突。这是优雅且正确的处理,但我会忽略对描述的处理,因为它不会改变概念)。
entires的感知排序(例如通过迭代Map
返回)取决于这些桶中条目的顺序。
每当重新定义大小时(因为地图超过其丰满度阈值),则桶的数量会发生变化,这意味着每个元素的位置可能会发生变化,因为铲斗位置也是从桶的数量中得出的。
答案 2 :(得分:5)
HashMap
根本不排序。对于按键值排序的地图,您应该使用TreeMap
代替。
来自TreeMap
的JavaDocs:
基于红黑树的实现 SortedMap接口。这个班 保证地图将在 按升序排序,按照排序 按键的自然顺序 class(参见Comparable),或者 在创建时提供比较器, 取决于哪个构造函数 使用
来自HashMap
的文档:
本课程不保证 地图的顺序;特别是, 它不保证订单 随着时间的推移会保持不变。
答案 3 :(得分:1)
Map
不是有序数据结构 - 您不应该依赖HashMap
中某个顺序的条目。某些Map
实施(例如LinkedHashMap
和TreeMap
)确实保证了某个订单,但HashMap
却没有。
如果您真的想知道内部发生了什么,请查找HashMap
的源代码 - 您可以在 src.zip 中找到它,它应该在您的JDK安装目录中。
HashMap
有许多“存储桶”,用于存储其条目。存储条目的桶由条目的密钥的哈希码确定。您在HashMap
中看到条目的顺序取决于键的哈希码。但是不要编写依赖于HashMap
中某个顺序的条目的程序 - 实现可能会在未来的Java版本中发生变化,然后您的程序将无法再运行。
答案 4 :(得分:1)
hashmap具有未定义的元素顺序
答案 5 :(得分:0)
哈希表中没有定义的排序。根据哈希码将密钥放入一个插槽中,但即使这样也不是一个简单的按顺序排列的代码。
答案 6 :(得分:0)
HashMap使用使用密钥的一部分生成的唯一哈希值来存储值。此哈希值映射到将要存储的地址。这就是它如何确保访问O(1)。
另一方面,LinkedHashmap会保留您添加到地图的顺序。