Java如何对HashMap或HashTable中的项进行排序?
我想知道Java在添加Java如何对HashMap或HashTable中的项进行排序?,java,map,hashtable,hashmap,hashcode,Java,Map,Hashtable,Hashmap,Hashcode,我想知道Java在添加Map(HashMap或Hashtable)时是如何排序的。密钥是按哈希代码、内存引用还是按分配优先级排序 这是因为我注意到Map中的相同对并不总是以相同的顺序排列HashMap根本不排序。对于按键值排序的映射,应改用TreeMap 从树映射的JavaDocs中: 基于红黑树的智能交通系统的实现 分类地图界面。这个班 保证地图将在 升序键顺序,根据 按照钥匙的自然顺序 类别(见可比),或由 创建时提供的比较器, 取决于所使用的构造函数 用过 从HashMap的文档中: 这个
Map
(HashMap
或Hashtable
)时是如何排序的。密钥是按哈希代码、内存引用还是按分配优先级排序
这是因为我注意到
Map
中的相同对并不总是以相同的顺序排列HashMap
根本不排序。对于按键值排序的映射,应改用TreeMap
从树映射的JavaDocs中:
基于红黑树的智能交通系统的实现
分类地图界面。这个班
保证地图将在
升序键顺序,根据
按照钥匙的自然顺序
类别(见可比),或由
创建时提供的比较器,
取决于所使用的构造函数
用过
从HashMap
的文档中:
这个类不保证
地图的顺序;特别地,
这并不保证订单
将随时间保持不变
Map
不是一个有序的数据结构-您不应该依赖于HashMap
中的条目具有特定的顺序。一些Map
实现,如LinkedHashMap
和TreeMap
确实保证了一定的顺序,但HashMap
却不能
如果您真的想知道内部发生了什么,请查找HashMap
的源代码-您可以在src.zip中找到它,它应该位于JDK安装目录中
HashMap
有许多“bucket”存储其条目。条目存储在哪个bucket中由条目键的散列码决定。在HashMap
中查看条目的顺序取决于键的哈希代码。但是,不要编写依赖于条目在HashMap
中的特定顺序的程序-在未来的Java版本中,实现可能会发生变化,然后您的程序将不再工作。哈希表中没有定义顺序。根据散列码,键被放入一个插槽中,但即使按照散列码的顺序,这也不是一个简单的顺序。散列映射具有未定义的元素顺序。无序;除此之外,你不能也不应该做任何假设
此类不保证地图的顺序;特别是,它不能保证订单在一段时间内保持不变
使用插入顺序
此实现与HashMap的不同之处在于,它维护一个贯穿其所有条目的双链接列表。此链表定义了迭代顺序,通常是将关键帧插入贴图的顺序(插入顺序)
,a使用键的自然或自定义顺序
映射根据其键的自然顺序进行排序,或者由映射创建时提供的比较器进行排序,具体取决于使用的构造函数
首先:HashMap
特别是不提供稳定和/或定义的顺序。因此,您观察到的任何内容都只是一个实现细节,您不能以任何方式依赖它
由于有时了解看似随机排序的原因很有用,因此以下是基本思路:
HashMap
有许多存储桶(实现为一个数组),用于存储条目
将项目添加到映射时,将根据其hashCode
的派生值和HashMap
的bucket大小将其分配给bucket。(请注意,存储桶可能已被占用,这称为碰撞。这是优雅而正确的处理方式,但我将在描述中忽略该处理方式,因为它不会改变概念)
实体的感知顺序(例如通过迭代映射返回的)取决于这些bucket中条目的顺序
每当重新设置大小时(因为映射超过了其满度阈值),存储桶的数量就会改变,这意味着每个元素的位置可能会改变,因为存储桶的位置也是从存储桶的数量派生出来的。HashMap使用使用部分键生成的唯一哈希值存储值。这个散列值映射到它将被存储的地址。这就是它如何确保访问O(1)
另一方面,LinkedHashmap保留了添加到地图的顺序。我从来没有说过要对它们进行排序。我想知道java doesHashMap是否不能保证O(1)。它试图做到最好,但在最坏的情况下,它是O(n),n=条目数(即使这不太可能(或者你的hashCode方法实现得很糟糕)),它并不总是提供恒定的时间性能,但通常它会尝试。然而,Hashmap每次都遵循相同的可预测序列。。。为什么?@pop-stack HashMap不能保证顺序。请参阅Stephen C在上的答案,了解它可能如何改变以及为什么会改变的详细信息。这些答案非常棒!一份备忘单列出所有地图、列表和Java设置之间的差异是非常棒的@popstack它对相同的数据遵循相同的顺序,因为顺序不是随机的。它使用相同的算法处理相同的数据,因此以相同的顺序处理也就不足为奇了。不要将无序与随机放置混淆!