首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么HashSet的keySet中的元素顺序从run变为run?

为什么HashSet的keySet中的元素顺序从run变为run?
EN

Stack Overflow用户
提问于 2014-07-16 03:37:54
回答 3查看 1.7K关注 0票数 6

我有一些使用标准Java集合的代码:数组、ArrayDeques、HashMaps、List、HashSets。我的代码应该是确定性的:所有元素的哈希代码、集合的初始内容等等都将只依赖于输入数据。代码的最终输出是由某个keySet()的HashMap生成的。

我注意到,生成的keySet中元素的顺序有时会在运行过程中发生变化。什么意思?

  • 一些标准集合具有非确定性行为(例如,某些内部对象的哈希代码是不确定的)?
  • 我自己的代码实际上是不确定的(例如,我忘记为某个类正确地覆盖hashCode() )?这可能意味着我在某个地方有一个bug (还没有被测试捕获),这就是我担心的原因。
  • 还有别的吗?

这种情况在Windows7 1.7.0_60上的JDK 1.7.0_60,x86中是一致的。据称,这种情况在JDK 1.8.0_05中不会发生(或者很少发生)。此外,在上述JDK之间切换时,结果keySet中元素的顺序(以及处理数据项的总体顺序)也会发生变化。

我怀疑这是HashSet的一些特性,但无法跟踪到特定的代码行。

UPD 1我并不真正需要确定性集,而且我知道HashSet没有提供任何保证。我只是想找出不确定行为的原因。如果是在图书馆代码里-好的。但是如果它在我的代码中-我可能要修复它。这就是问题所在。

UPD 2,当然,我在发布这个问题之后就找到了答案。就在1.7岁的HashMap.java开始时:

代码语言:javascript
运行
复制
/**
 * A randomizing value associated with this instance that is applied to
 * hash code of keys to make hash collisions harder to find. If 0 then
 * alternative hashing is disabled.
 */
transient int hashSeed = 0;

在1.8中,这种随机化似乎不再存在。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-18 18:51:15

只是在这里复制问题中已经包含的内容。快速查看源代码表明,在1.7中,HashMap确实具有不确定的行为,并且每个实例都以某种随机值播撒元素的散列。在1.8中,实现被改变了,随机化似乎不再存在。

票数 1
EN

Stack Overflow用户

发布于 2014-07-16 03:40:28

来自HashSet文档

它不能保证集合的迭代顺序;特别是,它不能保证随着时间的推移,顺序将保持不变。

票数 5
EN

Stack Overflow用户

发布于 2014-07-16 03:40:27

如果您需要一个稳定有序的HashSet,那么您应该按照javadoc使用LinkedHashSet

哈希表和集合接口的链接列表实现,具有可预测的迭代顺序

根据HashSet javadoc,

..。不能保证集合的迭代顺序。

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

https://stackoverflow.com/questions/24771793

复制
相关文章

相似问题

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