Java 如何对 HashMap 或 HashTable 中的项目进行排序?
Posted
技术标签:
【中文标题】Java 如何对 HashMap 或 HashTable 中的项目进行排序?【英文标题】:How does Java order items in a HashMap or a HashTable? 【发布时间】:2011-02-18 13:10:52 【问题描述】:我想知道添加 Map
(HashMap
或 Hashtable
)中的项目时 Java 是如何排序的。键是按哈希码、内存引用还是分配优先级排序...?
这是因为我注意到Map
中的相同对并不总是相同的顺序
【问题讨论】:
【参考方案1】:java.util.HashMap
是无序的;你不能也不应该假设除此之外的任何事情。
这个类不保证地图的顺序;特别是,它不保证订单会随着时间的推移保持不变。
java.util.LinkedHashMap
使用插入顺序。
此实现与
HashMap
的不同之处在于,它维护一个双向链表,贯穿其所有条目。这个链表定义了迭代顺序,通常是键插入映射的顺序(插入顺序)。
java.util.TreeMap
,SortedMap
,使用键的自然或自定义顺序。
地图根据其键的自然顺序排序,或者根据地图创建时提供的
Comparator
排序,具体取决于使用的构造函数。
【讨论】:
然而 Hashmap 每次都遵循相同的可预测序列...为什么? @pop stack HashMap 不保证顺序。请参阅 Stephen C 在***.com/questions/2144776/… 上的回答,详细了解它如何以及为什么会发生变化。 这样的回答太棒了!一个备忘单对于列出 Java 中所有 Map、List、Set 之间的差异非常棒! @popstack 对于相同的数据,它遵循相同的顺序,因为顺序不是随机的。它由相同的算法处理相同的数据,因此其顺序相同也就不足为奇了。不要将无序与随机放置混淆!【参考方案2】:首先:HashMap
特别不提供稳定和/或定义的排序。因此,您观察到的任何内容都只是一个实现细节,您不得以任何方式依赖它。
由于有时了解看似随机排序的原因很有用,因此基本思路如下:
HashMap
有多个桶(实现为数组)用于存储条目。
当一个项目被添加到地图时,它被分配到一个基于其hashCode
的值和HashMap
的桶大小的桶。 (请注意,桶可能已被占用,这称为冲突。处理得当且正确,但我将忽略该处理的描述,因为它不会改变概念)。
整体的感知顺序(例如通过迭代 Map
返回)取决于这些桶中条目的顺序。
每当重新散列大小时(因为地图超过了其填充度阈值),桶的数量就会发生变化,这意味着每个元素的位置可能会发生变化,因为桶的位置也是从桶的数量得出的。
【讨论】:
【参考方案3】:HashMap
根本不排序。对于按键值排序的地图,您应该改用TreeMap
。
来自TreeMap
的 JavaDocs:
基于红黑树的实现 SortedMap 接口。这节课 保证地图将在 升序键顺序,根据排序 键的自然顺序 类(参见 Comparable),或由 在创建时提供的比较器, 取决于哪个构造函数 用过。
来自HashMap
的文档:
这个类不保证 地图的顺序;特别是, 它不保证订单 随着时间的推移将保持不变。
【讨论】:
我从来没有说过我想让它们排序。我想知道java是否有【参考方案4】:Map
不是有序的数据结构 - 您不应依赖 HashMap
中的条目按特定顺序排列。一些Map
实现如LinkedHashMap
和TreeMap
确实保证一定的顺序,但HashMap
不保证。
如果你真的想知道内部发生了什么,请查找HashMap
的源代码 - 你可以在 src.zip 中找到它,它应该在你的 JDK 安装目录中。
HashMap
有许多“桶”用于存储其条目。条目存储在哪个桶中由条目的键的哈希码决定。您在HashMap
中看到条目的顺序取决于键的哈希码。但不要编写依赖于 HashMap
中特定顺序的条目的程序 - 在 Java 的未来版本中实现可能会发生变化,然后您的程序将不再工作。
【讨论】:
【参考方案5】:hashmap 的元素顺序未定义
【讨论】:
【参考方案6】:哈希表中没有定义的顺序。根据哈希码将密钥放入槽中,但即使这样也不是简单的按哈希码排序。
【讨论】:
【参考方案7】:HashMap 使用键的一部分生成的唯一哈希值存储值。此哈希值映射到将要存储的地址。这就是它确保访问 O(1) 的方式。
另一方面,LinkedHashmap 保留了您添加到地图的顺序。
【讨论】:
HashMap 不能保证 O(1)。它会尽力做到最好,但在最坏的情况下,它是 O(n),n = 条目数(即使这不太可能(或者你的 hashCode 方法实施得不好)) 同意它并不总是提供恒定时间的性能,但通常情况下,它确实会尝试。 java.sun.com/j2se/1.4.2/docs/api/java/util/HashMap.html以上是关于Java 如何对 HashMap 或 HashTable 中的项目进行排序?的主要内容,如果未能解决你的问题,请参考以下文章
Java 如何对 HashMap 或 HashTable 中的项目进行排序?