【问题标题】:'Dictionary Types' In .Net.Net 中的“字典类型”
【发布时间】:2014-05-24 16:59:45
【问题描述】:

我在 C# 中使用了相当多的通用字典。比如:

var example = new Dictionary<int, string> { 
                                        { 0, "Test0" }, 
                                        { 1, "Test1" } };

我隐约记得有人告诉我,在泛型出现之前,您可以使用 Hashtable()。基本相同,但没有特定类型(我认为值类型将被装箱)。

var example2 = new Hashtable {
                          {0, "Test0"},
                          {1, "Test1"} };

还有类似这样的问题讨论为什么我们更喜欢字典而不是哈希表 (Why is Dictionary preferred over hashtable?)。

但是所有其他“字典”类型呢

  • SortedDictionary&lt;K,V&gt; - 似乎像 Dictionary 一样工作,但它的 .Keys 集合已排序。不过我不知道你为什么会在意。
  • OrderedDictionary 不像 Hashtable 那样是非泛型的,但我无法理解与 Hashtable 不同的地方。 http://msdn.microsoft.com/en-us/library/system.collections.specialized.ordereddictionary.aspx 提到它的键没有像 SortedDictionary 那样排序,所以我只是不明白为什么或何时使用它。
  • ListDictionary - 当元素数量少于 10 个时,比 Hashtable 更小/更快(但它比通用字典快吗?)。再说一次,我不知道你什么时候会使用它。

我也对SortedList&lt;K,V&gt; 感到困惑。当我听到List 时,我不认为键/值对(也许我应该?)。它实现了IDictionary&lt;TKey,TValue&gt;。从这个问题,我可以看出它与 SortedDictionary 的不同之处在于它的性能特征(What's the difference between SortedList and SortedDictionary?

谁能简要解释一下何时使用哪种字典类型?

为了简单起见,假设我可以访问 .Net 4.5 或更高版本...那么也许 Hashtable 不再有用了?

【问题讨论】:

  • Ordered/SortedDictionarys 都早于 LINQ,这就是我认为它们存在的原因。在 ListDictionary 上不确定

标签: c# .net collections


【解决方案1】:

DictionaryHashtable 都表示使用了某种数据索引。查询索引需要一些时间,因此在少量元素时会变慢。

List 不使用索引,通常在末尾添加项目。插入项目时,其他项目“物理地”移动以为新元素腾出空间,移除项目时,其他项目移动以缩小间隙。

Dictionary 通常不保留顺序,并且可能包含内存间隙。添加项目时,这些空白可能会被新项目填补。遍历 Dictionary 会以不同的顺序返回项目。

排序是一种不同的排序方式——它不保留添加项目的顺序,而是遵循规则来确定添加项目的位置。

有趣的是,当泛化发生时ArrayList 变成了List&lt;T&gt;,而Hashtable 变成了Dictionary&lt;T, U&gt;——两者都从名称中删除了技术方面的内容,只留下了抽象的名称。

【讨论】:

    【解决方案2】:

    使用Dictionary&lt;TKey,TValue&gt;。没有理由使用旧的非通用哈希表。


    有序字典

    如果字典中项目的插入顺序很重要,则使用OrderedDictionary

    假设我有一张儿童与他们最喜欢的冰淇淋的映射。

    OrderedDictioanry childToIcecream = new OrderedDictionary();
    childToIcecream["Jake"] = "Vanilla";
    childToIcecream["Kevin"] = "Chocolate";
    childToIcecream["Megan"] = "Strawberry";
    

    每天一个孩子轮流得到一个额外的勺子。我们可以将天数(星期日 = 0,星期一 = 1..)用孩子的数量做模,然后从字典中拉出他们的索引来选择是谁的幸运日。这当然只有在字典保持顺序时才有效。否则我需要一个单独的List&lt;string&gt; 来维护订单。您在一个容器中获得键/值对和订单。

    不幸的是没有通用的有序字典,但是有人发布了一个实现here


    排序字典

    排序字典也是如此。如果您需要对键/值对进行排序,这将节省您始终保持排序的时间,而不必在需要时进行昂贵的排序操作。

    SortedDictionary<char, string> letterToWord = new SortedDictionary<char, string>();
    letterToWord['b'] = "bat";    
    letterToWord['c'] = "cat";    
    letterToWord['a'] = "apple";
    

    假设你有一个像上面这样的字典,除了用户可以在运行时建立字母关联。您总是希望按字母顺序显示它,因此在添加每个新项目时始终保持排序是有意义的。


    TLDR;除非您有需要对其进行排序或排序的情况,否则请始终使用Dictionary&lt;TKey, TValue&gt;

    【讨论】:

      猜你喜欢
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-11
      • 2019-10-14
      • 2023-04-06
      • 1970-01-01
      • 2012-02-09
      相关资源
      最近更新 更多