简体   繁体   English

我如何使用HashSet <T> 作为字典键?

[英]How do I use HashSet<T> as a dictionary key?

I wish to use HashSet<T> as the key to a Dictionary: 我希望使用HashSet<T>作为Dictionary的键:

Dictionary<HashSet<T>, TValue> myDictionary = new Dictionary<HashSet<T>, TValue>();

I want to look up values from the dictionary such that two different instances of HashSet<T> that contain the same items will return the same value. 我想从字典中查找值,以便包含相同项的两个不同的HashSet<T>实例将返回相同的值。

HashSet<T> 's implementations of Equals() and GetHashCode() don't seem to do this (I think they're just the defaults). HashSet<T>Equals()GetHashCode()实现似乎没有这样做(我认为它们只是默认值)。 I can override Equals() to use SetEquals() but what about GetHashCode() ? 我可以重写Equals()以使用SetEquals()但是GetHashCode()呢? I feel like I am missing something here... 我觉得我在这里错过了一些东西......

您可以使用HashSet<T>提供的set comparer:

var myDictionary = new Dictionary<HashSet<T>, TValue>(HashSet<T>.CreateSetComparer());

digEmAll's answer is clearly the better choice in practice, since it uses built in code instead of reinventing the wheel. digEmAll的答案显然是实践中更好的选择,因为它使用内置代码而不是重新发明轮子。 But I'll leave this as a sample implementation. 但我将把它作为一个示例实现。


You can use implement an IEqualityComparer<HashSet<T>> that uses SetEquals . 您可以使用实现使用SetEqualsIEqualityComparer<HashSet<T>> Then pass it to the constructor of the Dictionary. 然后将它传递给Dictionary的构造函数。 Something like the following(Didn't test it): 像下面的东西(没有测试):

class HashSetEqualityComparer<T>: IEqualityComparer<HashSet<T>>
{
    public int GetHashCode(HashSet<T> hashSet)
    {
        if(hashSet == null)
           return 0;
        int h = 0x14345843; //some arbitrary number
        foreach(T elem in hashSet)
        {
            h = unchecked(h + hashSet.Comparer.GetHashCode(elem));
        }
        return h;
    }

    public bool Equals(HashSet<T> set1, HashSet<T> set2)
    {
        if(set1 == set2)
            return true;
        if(set1 == null || set2 == null)
            return false;
        return set1.SetEquals(set2);
    }
}

Note that the hash function here is commutative, that's important because the enumeration order of the elements in the set is undefined. 请注意,这里的哈希函数是可交换的,这很重要,因为集合中元素的枚举顺序是未定义的。

One other interesting point is that you can't just use elem.GetHashCode since that will give wrong results when a custom equality comparer was supplied to the set. 另一个有趣的一点是,您不能只使用elem.GetHashCode因为当向集合提供自定义相等比较器时,这会产生错误的结果。

您可以向Dictionary构造函数提供IEqualityComparer<HashSet<T>> ,并在该比较器中进行所需的实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM