是否 HashSet .NET 3.5 中引入的集合在迭代时保留插入顺序 foreach?

文档 声明该集合未排序,但它没有说明任何有关插入顺序的信息。预发布 BCL 博客条目 声明它是无序的,但是 本文 声明它旨在保留插入顺序。我有限的测试表明,该顺序被保留,但这可能是巧合。

有帮助吗?

解决方案

此HashSet的MSDN页具体表示:

  

一个组是不包含重复的元件,并且其元素是在没有特定的顺序的集合。

其他提示

我觉得这篇文章,声称它保留了订购只是简单的错误。简单测试,插入以很可能是保留由于内部结构,但它不能保证并不总是这样的。我会试着来了一个反.

编辑:这里的反:

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        var set = new HashSet<int>();

        set.Add(1);
        set.Add(2);
        set.Add(3);
        set.Remove(2);
        set.Add(4);


        foreach (int x in set)
        {
            Console.WriteLine(x);
        }
    }
}

这印花1,4,3尽管3具有直之前插入4.

它的 可能的 如果你永远不会删除任何项目,它将保留插入序。我不知道,但我不能完全感到惊讶。然而,我认为这将是一个非常坏的主意,依靠的是:

  • 它不记录工作的方式,该文件明确指出,它不排序。
  • 我还没看过内部结构或源代码(我没有,显然)-我必须仔细研究他们在作出任何这类权利要求在一个坚定的方式。
  • 执行可能很容易地改变之间的版本的框架。依靠这将是喜欢依赖 string.GetHashCode 执行情况不改变,其中有些人没有回来。净1.1天,然后他们被烧的时候的执行情况 有没有 改变。网2.0...

文档状态:

  

一个的HashSet <(中<(T>)>)收集未排序并且不能包含重复的元素。如果顺序或元素复制比你的应用程序的性能更重要的是,考虑使用列表<(中<(T>)>)类与排序方法在一起。

因此也无所谓是否真正保持在当前实现元素的顺序,因为它没有记录,因为这样做,即使它似乎现在这可能会在未来的任何一点改变(即使在修复程序来框架)。

您应该对编程的记载合约的,不是的实施细则

没有,散列集将不保留插入顺序,至少不能预见的。你可以使用LinkedHashSet(JAVA),或等效的。一个LinkedHashSet将会维持秩序。

<击>如果您要订购,你甚至不应该在第一时间使用一组 ...其有序元素不言,除非在特殊情况下。

编辑:听起来像我说教: - /抱歉

阅读源代码 HashSet.AddIfNotPresent 你可以看到插入顺序被保留 假设没有任何删除.

因此 new HashSet<string> { "Tom", "Dick", "Harry" } 保留顺序,但如果您随后删除 Dick 并添加 Rick,则顺序将为 [“Tom”、“Rick”、“Harry”]。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top