HashSet在枚举时是否保持顺序?

6
这篇 StackOverflow答案 完全描述了 HashSet 无序的特性,其项目枚举顺序是不确定的,不能依赖它。

然而,

这带来了另一个问题:如果没有插入或删除操作,我是否应该依赖两个或多个连续枚举之间的枚举顺序?

例如,假设我已经向 HashSet 中添加了一些项:

HashSet<int> set = new HashSet<int>();
set.Add(1);
set.Add(2);
set.Add(3);
set.Add(4);
set.Add(5);

现在,当我通过foreach枚举该集合,假设我收到以下序列:
// Result: 1, 3, 4, 5, 2.

问题是:如果我多次枚举集合,不做任何修改,那么顺序会保持不变吗?是否总是相同的?

5
即使这是真的,也应该有记录。由于没有记录,我不会依赖它。在未来框架的更新中,它可能随时崩溃。如果需要保证枚举顺序,为什么会使用哈希?根据您的需求,您选择的数据结构完全错误。 - Darin Dimitrov
1
由于哈希集合基本上是一个具有固定槽顺序的哈希表,如果您不对集合进行任何修改,迭代顺序是恒定的。但是,您是否应该依赖于此呢?我认为不应该,您应该避免依赖于此。 - poke
嗯,我正在尝试仅依靠一组连续枚举顺序,这就是全部。我需要的数据结构是O(1)添加/删除加上上面问题的积极答案。有吗? - AgentFire
1
拉取GetEnumerator()的实现并自行判断。 - paparazzo
1
只要对hashset没有进行更新,当前实现每次都会产生相同的顺序。我相信这就是你问题的答案。在.NET进行下一个修复补丁之后,无法保证hashset会做出什么样的行为,这就是未记录的行为意味着它可能会毫无明显原因地发生改变。 - Lasse V. Karlsen
显示剩余5条评论
1个回答

4
实际上,在枚举值之间,它们可能总是相同的,但这种假设在IEnumerable的描述中没有提供,实现者可以决定以任何顺序返回它们。
谁知道它在底层做了什么,以及将来是否会继续以同样的方式进行。例如,HashSet的未来实现可能被优化为检测低内存条件并重新排列其内容,从而影响它们返回的顺序。因此,99.9%的时间它们会以相同的顺序返回,但如果您开始耗尽内存资源,它会突然以不同的顺序返回事物。
底线是我不会依赖于枚举顺序始终保持一致。如果顺序对您很重要,请使用set.OrderBy(x => x)对其进行foreach,以便您可以确保它按照您想要的顺序排序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接