首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >HashSet中元素的顺序是如何工作的?

HashSet中元素的顺序是如何工作的?
EN

Stack Overflow用户
提问于 2014-01-21 23:27:15
回答 4查看 3K关注 0票数 4

我知道HashSet中元素的顺序应该是任意的。但出于好奇,有人能告诉我顺序是如何确定的吗?

我注意到,当我插入两个元素(例如A和B)时,顺序将为A, B,然后再次重新执行相同的代码将得到B, A,然后第三次重新执行它将得到A, B

我的意思是,这有点不确定,而且有点奇怪。

EN

回答 4

Stack Overflow用户

发布于 2014-01-21 23:35:02

顺序由Hash Map/Set中使用的哈希算法、该Map的确切设置和对象的Hashcode确定。

如果您的对象在多次运行时具有一致的哈希码(例如字符串),并且以相同的顺序放入具有相同设置的映射中,那么通常它们每次都会以相同的顺序出现。如果他们不这样做,那么他们就不会这么做。

在这里可以看到HashMap的源代码:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashMap.java

事实上,该来源中的一句有趣的话是:

这个类不能保证映射的顺序;特别是,它不能保证顺序随着时间的推移保持不变。

因此,不仅您的程序每次运行时顺序可能不同,而且事实上,API本身也不能保证即使在程序的一次运行中,顺序也将保持不变!

“不确定且有点奇怪”是对HashMap排序的一个很好的描述--实际上文档上也是这么说的。如果您想要排序,请使用LinkedHashMapTreeMap。如果你不想要排序,那么不用担心,通过有效地随机排序,HashMap可以从它所保证的方法的行为中给你极快的响应!

票数 4
EN

Stack Overflow用户

发布于 2014-01-21 23:40:11

原则上有两个因素:

您的密钥的

  1. 哈希码可能是不确定的,当您使用依赖于内存的默认hashCode实现时就是这种情况location
  2. HashSet本身可能是不确定的,看看HashMap.initHashSeedAsNeeded (HashSet使用标准Oracle SDK中的HashMap作为底层数据结构),这取决于它可以使用sun.misc.Hashing.randomHashSeed(this)初始化hashSeed字段,然后在计算key

的hashCode时使用该字段

随机化对于实现概率性能保证可能很重要。这就是javadoc对hashSeed的描述:

/** *与此实例关联的随机化值,应用于

*键的散列代码,使散列冲突更难发现。如果为0,则

*禁用备用哈希。*/

票数 3
EN

Stack Overflow用户

发布于 2014-01-21 23:42:51

除非您在HashSet中添加/删除某些内容,否则顺序不会更改(实际上)。

该顺序基于内部hashtable存储桶。这取决于对象的hashCode()和哈希表的大小。

简化示例:

A的哈希码为10,B的hashcode为11。哈希表的大小为2。哈希码到哈希表中的位置的映射将纯粹基于最后一位,即偶数哈希码进入表,奇数哈希码进入table1。

代码语言:javascript
复制
table[0] = { A }
table[1] = { B }

迭代这些值现在很可能是A,B。只要表的大小保持不变,每次结果都应该是可重现的。

使用hashCode 12添加第三个元素C(当不调整表大小时)也会将其添加到bucket #0中。

代码语言:javascript
复制
table[0] = { A, C }
table[1] = { B }

因此,您的迭代将是A,C,B,或者取决于您是否在C之前插入A: C,A,B

添加元素实际上会调整表的大小,并使用调整后的映射重新散列。例如,表的大小将加倍,并且最后2位可用于确定桶

代码语言:javascript
复制
table[0] = { C }
table[1] = {   }
table[2] = { A }
table[3] = { B }

而且只需添加一个元素,顺序就会完全改变。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21262299

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档