【问题标题】:Why does the HashSet preserve insertion order? [duplicate]为什么 HashSet 保留插入顺序? [复制]
【发布时间】:2020-04-07 07:40:34
【问题描述】:

也许我做错了,但我正在尝试通过将 List 转换为 HashSet 来对其进行洗牌,

List<Article> art = new List<Article>(rootobject.articles);
HashSet<Article> setart = new HashSet<Article>(art);

当我遍历这两个列表时,

foreach (Article a in art)
{
    Console.WriteLine(a.title)
}

和哈希集,

foreach (Article a in setart)
{
    Console.WriteLine(a.title)
}

我以完全相同的顺序得到完全相同的输出。我在想默认情况下使用强制转换操作应该随机化列表,但似乎并非如此。

我哪里错了?

【问题讨论】:

  • 为什么你认为将数据放入哈希集中会打乱它?
  • Article是如何实现的?它是否覆盖了GetHashCodeEquals 方法?请同时参考hashset的备注部分
  • 如果你想打乱一个列表,你可以将第一个元素与随机元素交换,将第二个元素与随机元素交换,...​​,将第 n 个元素与随机元素交换。
  • HashSet不保证插入顺序;订单可能取决于 .Net 版本、项目本身等,也可能取决于 HashSet shuffle 项目。项目只是可以(不是必须)按任意顺序排列
  • 查看重复项以获得您问题的答案,以及以随机顺序对列表进行排序的更好方法。

标签: c# list hashset


【解决方案1】:
public HashSet(IEnumerable<T> collection);

调用这个构造函数:

public HashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer);

如果集合还不是 HashSet,则有一个 foreach 会按照来自底层对象的 GetHashCode()-Function 的顺序复制集合中的项目。

这样,您的 HashSet 可能与您的列表中的顺序不完全一致。但正如您在示例中看到的那样,顺序可能仍然相同。

这是对 HashSet.cs 代码的引用。

https://github.com/microsoft/referencesource/blob/master/System.Core/System/Collections/Generic/HashSet.cs

编辑我的答案,感谢回复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-14
    • 2018-12-10
    • 1970-01-01
    • 2014-05-29
    • 2022-01-21
    • 2012-03-24
    • 1970-01-01
    相关资源
    最近更新 更多