【问题标题】:Does HashSet preserve insertion order *if no items are deleted*HashSet 是否保留插入顺序*如果没有项目被删除*
【发布时间】:2019-01-18 09:52:11
【问题描述】:

我知道有几个关于 HashSet 和订单保留的问题,非常简单的测试表明,如果添加和删除项目,订单将根本不会保留。

但我的问题明确涉及如果没有从 HashSet 中删除任何项目,是否保留插入顺序。

早在 2009 年 Jon Skeet (https://stackoverflow.com/a/657289/10894153) 就说过:

如果您从不移除任何项目,它可能会保留插入顺序。我不确定,但我不会完全感到惊讶。

他当时的理由是:

我没有查看内部结构或源代码(显然我没有)。

显然,这已经改变了,并且随着 .NET 现在是开源的,我想知道是否有人可以确定地验证插入顺序是否确实保留在 HashSet 上,而没有删除任何项目。

在问这个问题之前,我已经执行了几个 快速 测试,将 1000 个项目添加到 HashSet 并保留了插入顺序,但这绝不是证明它总是即使没有发生删除的情况。

编辑

正如 HimBromBeere 所指出的,HashSet 的官方文档声明不保留顺序,因此即使当前实现保持(尽管很明显它们确实保证)插入顺序这可能会在未来发生变化。

话虽如此,我感兴趣的是在当前实现中没有发生删除时是否保持插入顺序(.NET 4.7.2)

【问题讨论】:

标签: c# .net hashset


【解决方案1】:

话虽如此,我对插入顺序是否是感兴趣的 在当前实现中没有发生删除时保持。

是的,它在 4.7.2 中维护。截至 2019 年 1 月 18 日。

我怀疑这里的部分问题是理解合同和实施之间的区别。

4.7.2 中HashSet实现将保持插入顺序(如果您不删除项目)。但你最初并没有这么问。您问是否:

保证插入顺序

对于这个问题,答案是肯定的。方法的保证不是由实现定义的,而是由合约定义的。 contract 声明:

集合是不包含重复元素的集合,其 元素没有特定的顺序。

除了没有关于订单的没有保证之外,根本没有办法以任何其他方式来阅读该声明。

现在 - 您可以选择忽略保证,并根据当前行为部署应用程序。而且,只要微软没有发布改变行为的 Windows 更新补丁(或者你的代码在不同的实现中运行,比如 Mono 等),你可能会没事的。但可能肯定(或保证)不同。

【讨论】:

  • 更新问题以维护替换保证。
  • 无论如何,我的论点仍然存在。 Microsoft 有 100% 的权利在明天发布一个改变这种行为的补丁。
猜你喜欢
  • 2010-10-14
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多