为啥 .Net 字典看起来像是排序的? [复制]

Posted

技术标签:

【中文标题】为啥 .Net 字典看起来像是排序的? [复制]【英文标题】:Why does the .Net Dictionary look like it is sorted? [duplicate]为什么 .Net 字典看起来像是排序的? [复制] 【发布时间】:2012-04-07 01:20:42 【问题描述】:

我正在查看我的同事签入的一些代码,它看起来像这样:

return list.OrderBy(item => item.Order).ToDictionary(item => item.Id);

我立即告诉我的同事他的代码是错误的,因为Dictionary 是一个哈希表,一个未排序的集合。我说,他应该使用保持顺序的集合,或者稍后在他使用foreach 从字典中读取项目时对项目进行排序。

但他回答“不,不,我的代码是正确的!看:现在我已经添加了OrderBy,项目以正确的顺序显示。”

事实证明,在测试用例上,他是对的。我尝试了一些其他数据,但它仍然是完美排序的!

我告诉他他不应该依赖这种行为,但他不同意,我无法解释原因。此外,我对为什么订单似乎经常被保留很感兴趣。

所以我的问题是......为什么Dictionary,一个根本上未排序的集合,看起来很像它是排序的?

【问题讨论】:

Dictionary 不保证集合是无序的。它不会故意使用 Random。是的,代码错了。 是的,贾斯汀,这是重复的。您链接的问题的答案是我想要的。你怎么能在这么多关于字典的问题中这么快找到重复的?我搜索并找不到它。谢谢! 我不知道(这就是我将其作为评论发布的原因)但我想这与 SQL 中的相同:SELECT 返回的行以未指定的顺序返回,除非包括ORDER BY 子句。通常,特别是在小型数据集中,行以它们插入的相同顺序返回,这让很多人感到困惑。 (我总是告诉人们,如果他们完全关心结果的顺序,请添加 ORDER BY。没有它它可能工作,但它也可能会严重损坏。) @EldritchConundrum -- 这是.net dictionary order 在 Google 上的第一个结果。我发现 Google 有时比内置搜索效果更好。 【参考方案1】:

在遍历字典时,您会在 the order they were inserted to the dictionary 中获得其中的项目。

在示例中,对列表进行排序,然后将每个项目依次添加到字典中。

最终结果是字典中的项目按照列表的排序顺序。

但是,Dictionary 的当前实现恰好是这种情况 - 不能保证它会保持这种状态。

如果您需要将Dictionary 中的项目按特定顺序排列,您应该使用SortedDictionary

【讨论】:

您能否更好地解释一下为什么要对它们进行排序。我会说他们是由他们的哈希“排序”的,即属性“Id” @LuisFilipe - 我不关注。该列表已排序(list.OrderBy(item => item.Order) 然后转换为Dictionary。转换通过将每个项目添加到字典来进行。字典中的项目是“有序”的,因为它们是按插入顺序排列的。因为它们是 按顺序插入,字典按顺序。 这是否由规范/合同保证,或者它是如何编写特定实现的工件?如果它是有保证的行为,引用将是有用的。 @MichaelKjörling - 无法保证,这只是当前版本的Dictionary 的实现方式。 Luis,实际上键是按哈希相关的顺序存储的,但值不是,字典枚举器使用值存储。【参考方案2】:

它是排序的,因为Dictionary 是如何实现的(在你的情况下,项目是按顺序添加的)。但这是实现细节

告诉你的同事存在一个SortedDictionary 类,这应该让他相信我们不能用简单的Dictionary 来依赖项目订单;)

【讨论】:

这是一个实现细节,当然,但我认为它不会改变。也许可以说只有 Add() 的字典确实保留了顺序。 @EldritchConundrum 真的,你不应该这样假设。目前是这样,但在未来的版本中可能不会。想想框架的其他实现(例如 Mono),不能保证它们以相同的方式实现 Dictionary。 是的。更重要的是,现在我知道如何构建我同事的代码将失败的测试用例;)我只需要在 foreach 之前删除和添加。

以上是关于为啥 .Net 字典看起来像是排序的? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Python 在格式化时将此字符串解释为字典? [复制]

为啥我在 python 中的字典总是有序的? [复制]

为啥 .NET 中没有 SortedList<T>? [关闭]

根据字典对列重新排序

为啥java中有两个接口可比较和比较器用于对集合进行排序? [复制]

数字按字典序怎么排?