.NET词典中的重复键?

时间:2020-03-06 14:50:52  来源:igfitidea点击:

.NET基类库中是否有任何允许使用重复键的字典类?我发现的唯一解决方案是创建一个类,例如:

Dictionary<string, List<object>>

但这实际上使人恼火。在Java中,我相信MultiMap可以完成此任务,但是无法在.NET中找到类似物。

解决方案

我认为诸如List <KeyValuePair <object,object >>之类的东西可以完成这项工作。

重复的密钥破坏了字典的整个契约。在字典中,每个键都是唯一的,并映射到单个值。如果要将一个对象链接到任意数量的其他对象,则最好的选择可能是类似于DataSet(通常是表)。将密钥放在一列中,将值放在另一列中。这比字典要慢得多,但这是我们失去对关键对象进行哈希处理的能力的折衷方案。

我们是说完全一致,而不是实际重复吗?否则,哈希表将无法工作。

Congruent表示两个单独的键可以哈希为等效值,但是键不相等。

例如:假设哈希表的哈希函数只是hashval = key mod3. 1和4都映射为1,但是它们的值不同。这就是列表想法发挥作用的地方。

当我们需要查找1时,该值将散列为1,则遍历该列表,直到找到Key = 1.

如果允许插入重复的键,则将无法区分哪个键映射到哪个值。

如果同时使用字符串作为键和值,则可以使用System.Collections.Specialized.NameValueCollection,它将通过GetValues(string key)方法返回字符串值的数组。

我刚遇到PowerCollections库,该库除其他外包括一个称为MultiDictionary的类。这巧妙地包装了这种类型的功能。

NameValueCollection在一个键(也是一个字符串)下支持多个字符串值,但这是我所知道的唯一示例。

当我遇到需要那种功能的情况时,我倾向于创建与示例类似的构造。

如果我们使用的是.NET 3.5,请使用Lookup类。

编辑:通常使用Enumerable.ToLookup创建Lookup。这确实假定我们以后不需要更改它,但是我通常认为这已经足够了。

如果这对我们不起作用,那么我认为框架中没有什么可以帮助,并且使用字典就可以了:(

看一下C5的HashBag类。

关于使用Lookup的非常重要的注意事项:

我们可以通过在实现了IEnumerable(T)的对象上调用ToLookup来创建一个Lookupup(TKey,TElement)的实例。

没有公共构造函数来创建Lookup(TKey,TElement)的新实例。此外," Lookup(TKey,TElement)"对象是不可变的,也就是说,创建后无法从" Lookup(TKey,TElement)"对象中添加或者删除元素或者键。

(来自MSDN)

我认为这将是大多数用途的止挡物。

List类实际上对于包含要在集合上进行迭代的重复项的键/值集合非常有效。例子:

List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();

// add some values to the collection here

for (int i = 0;  i < list.Count;  i++)
{
    Print(list[i].Key, list[i].Value);
}

在回答原始问题。像"字典<字符串,列表<对象>>"之类的东西在"代码项目"的名为" MultiMap"的类中实现。

我们可以在以下链接中找到更多信息:
http://www.codeproject.com/KB/cs/MultiKeyDictionary.aspx