【问题标题】:When I iterate through a Dictionary (.NET generic data structure) will it be in the same order that I added them?当我遍历字典(.NET 通用数据结构)时,它的顺序是否与我添加它们的顺序相同?
【发布时间】:2010-09-20 11:14:08
【问题描述】:

我有一个字典,我通常用一个键访问,所以我需要快速随机访问读取。但是,对于一个功能,我需要处理字典中顺序很重要的每个项目。它似乎在测试中工作正常。依赖字典中项目的顺序可以吗?

【问题讨论】:

    标签: .net data-structures dictionary


    【解决方案1】:

    没有。如果您想让您的钥匙井井有条,最好使用SortedDictionary

    编辑: 或者,如果您想跟踪添加项目的顺序,请将您的密钥添加到链接列表中。

    【讨论】:

    • 使用排序字典与按添加顺序遍历项目没有直接关系(见主题)
    【解决方案2】:

    没有。如果您需要保留订单,您还应该有一个物品清单。您可以将所需的所有操作封装在自己的集合类中,这样可以同时更新字典和列表。

    不幸的是,.NET 本身没有支持这一点的字典 - 这是一个相当常见的请求 - Java 有,就像 LinkedHashMap

    【讨论】:

      【解决方案3】:

      tpowerDictionarySortedDictionary 非常相似,因为它们都拥有一组对象,可以通过键访问。它们的不同之处在于它们的内部构建方式。

      据我所知,Dictionary 的插入速度更快,而SortedDictionary 建立在二叉树搜索算法之上,读取速度更快。

      不过,在这两种情况下,内部顺序都是由键顺序维护的。无法保证您遍历整个集合的顺序与您插入项目的顺序相同。

      在这种情况下,您可能需要同时存储列表和字典以满足您的不同需求。

      【讨论】:

      • 对于字典,顺序根本没有定义(并且可以随着大小的变化而变化);它不依赖于键 order - 但显然取决于键值、它们的哈希、桶的数量等。
      • 重新性能; SortedDictionary 的阅读速度较慢; SortedList 和 SortedDictionary 的 O(log n),而 Dictionary 的 O(1)。在这两种排序中,SortedList 占用的内存更少,插入 预排序 数据的速度更快(对于未排序的数据,SortedDictionary 插入速度更快)。
      【解决方案4】:

      文档明确指出“出于枚举的目的,字典中的每个项目都被视为表示值及其键的 KeyValuePair)>) 结构。中的顺序返回的项目是未定义的。”但我不相信。

      在我执行的所有测试中,项目总是按插入排序。

      我觉得这很奇怪,因为我还测试了 HashMap 和 LinkedHashMap(在 Java 中),并且 HashMap 中的顺序 不正确 正如预期的那样,但正如 Jon Skeet 所说,LinkedHashMap 中的顺序是。

      任何人都可以用字典指出失败测试吗?

      这是我用来测试的代码:

              IDictionary<string, int> dic = new Dictionary<string, int>(10);
      
              Console.WriteLine("Adding ...");
              for (int i = 0; i < 1000000; i++)
              {
                  Guid guid = Guid.NewGuid();
                  dic.Add(guid.ToString(), i);
              }
              Console.WriteLine("Testing ...");
      
              bool first = true;
              int lastItem = 0;
              foreach (var item in dic.Values)
              {
                  if (first)
                  {
                      first = false;
                  }
                  else
                  {
                      if (lastItem != item - 1)
                      {
                          Console.WriteLine("Test Failed !");
                          break;
                      }
      
                  }
                  lastItem = item;
              }
              Console.WriteLine("Done.");
      

      【讨论】:

      • 嗯...很有趣!即使我强制进行大量删除等,它也保持相当稳定。尽管如此,如果文档说“未定义”,那么忽略它们并不是一个好主意……即使它今天很稳定,也不必如此。
      • 你绝对不能依靠这个测试来证明字典将永远保持排序。可能是内存中的其他更改甚至插入/删除之间的时间都会影响顺序,唯一确定的方法是找出字典在幕后是如何工作的,这不是一项简单的任务。 .
      【解决方案5】:

      您绝对不能依赖 Dictionary 按添加顺序返回结果 - 正如文档所述。

      在测试中,Dictionary 似乎总是按照添加的顺序枚举 KeyValuePairs。但是, Dictionary 的 Mono 实现没有。 Mono 在实现行为时遵循文档,我假设他们看到了文档的那部分,然后以某种不维护顺序的方式实现。

      另一种选择是使用 OrderedDictionary,它维持秩序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-26
        • 1970-01-01
        • 2012-02-29
        • 1970-01-01
        相关资源
        最近更新 更多