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