【问题标题】:Whats the difference between indexed retrieval and keyed retrieval索引检索和键控检索有什么区别
【发布时间】:2020-08-22 12:20:34
【问题描述】:

查看KeyedCollection 的文档,我阅读了以下内容::

KeyedCollection 类提供 O(1) 索引检索和接近 O(1) 的键控检索。

https://docs.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.keyedcollection-2?view=netcore-3.1

我不完全理解这意味着什么。我个人认为索引检索和键检索是相同的,因为字典按键索引。我想我对“索引检索”和“键控检索”这两个术语感到有点模糊。

那么有什么区别,为什么肤色不一样?

附加信息: 我个人想使用keyedCollection,因为我有一个列表会添加很多。有时我需要通过 id 获取项目 - Guid 并返回一些数据。我还会定期检查列表并删除我不再使用的所有项目。

样品;

    /// <summary>
    /// A collection of leases. Implements <see cref="KeyedCollection{TKey,TItem}"/> which is a dictionary-list hybrid.
    /// </summary>
    public class LeaseInfoCollection : KeyedCollection<Guid, LeaseInfo>
    {
        #region Construction and Destruction

        /// <inheritdoc />
        public LeaseInfoCollection()
        {
        }

        /// <inheritdoc />
        public LeaseInfoCollection(IEqualityComparer<Guid> comparer)
            : base(comparer)
        {
        }

        /// <inheritdoc />
        public LeaseInfoCollection(IEqualityComparer<Guid> comparer, int dictionaryCreationThreshold)
            : base(comparer, dictionaryCreationThreshold)
        {
        }

        #endregion

        #region Overrides of KeyedCollection<string,LeaseInfo>

        /// <inheritdoc />
        protected override Guid GetKeyForItem(LeaseInfo item)
        {
            return item.LeaseId;
        }

        #endregion
    }

【问题讨论】:

  • 提示:要将自定义对象用作基于其属性的字典键,您必须在自定义对象上实现GetHashCode()Equals()。哈希码的可能值介于 int.MinValueint.MaxValue 之间,因此很明显可能会发生冲突。
  • 只是索引检索是“按索引”(myCollection[i]),键控是“按键”(myCollection[myKey])。索引指的是集合中的特定位置,而具有特定键的元素的位置可以在集合中的任何位置,这取决于数据结构如何处理键控。因此,您需要首先将键映射到位置,这对时间复杂度(希望)影响很小。
  • @Fildor 说得通——太棒了
  • @John 所以,如果我说得对,我目前将 MyCustomObject.Id 作为 keyedcollection 的“键”索引器。然后,我还应该覆盖 gethashcode 以使用 guid,以便 dict 索引基于此 - 还是我错了?我现在认为我根本不需要 keyedcollection,我可以重写 gethashcode 以使用 guid,然后改用字典 - 有什么建议吗?
  • 忽略最后的评论 - 我是愚蠢的。

标签: c# list collections complexity-theory


【解决方案1】:

这个问题的答案在documentation的下一段:

KeyedCollection&lt;TKey,TItem&gt; 类是集合之间的混合 基于IList&lt;T&gt; 通用接口和一个基于 IDictionary&lt;TKey,TValue&gt; 通用接口。喜欢集合基于 IList&lt;T&gt; 通用接口,KeyedCollection&lt;TKey,TItem&gt; 是一个 项目的索引列表。喜欢的集合基于 IDictionary&lt;TKey,TValue&gt; 通用接口, KeyedCollection&lt;TKey,TItem&gt; 有一个与每个元素关联的键。

从本段中我们可以了解到,我们可以使用它们的序号索引或它们的键来访问 KeyedCollection 集合的元素。

这里是示例(基于来自MSDN 的示例)来展示这两种检索KeyedCollection 元素的方法:

public class OrderItem
{
    public OrderItem(string partNumber) => PartNumber = partNumber;

    public string PartNumber { get; }
}

// Custom KeyedCollection.
public class SimpleOrder : KeyedCollection<string, OrderItem>
{
    // Here we define how to get Key from Item for our custom KeyedCollection.
    protected override string GetKeyForItem(OrderItem item) => item.PartNumber;
}

internal static class Program
{
    private static void Main()
    {
        KeyedCollection<string, OrderItem> kc = new SimpleOrder();

        kc.Add(new OrderItem("#0"));
        kc.Add(new OrderItem("#1"));

        // Retrieve item by index.
        Console.WriteLine(kc[0].PartNumber);

        // Retrieve item by key.
        Console.WriteLine(kc["#1"].PartNumber);
    }
}

【讨论】:

  • 我仍然不清楚后面的文字,但是当你像这样把它串在一起时,它是有道理的——非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-01
  • 2016-06-24
  • 2020-01-26
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 2010-09-10
相关资源
最近更新 更多