如何使用HashSet 作为字典键?
我希望使用HashSet
作为Dictionary的键:
Dictionary<HashSet, TValue> myDictionary = new Dictionary<HashSet, TValue>();
我想从字典中查找值,以便包含相同项的两个不同的HashSet
实例将返回相同的值。
HashSet
的Equals()
和GetHashCode()
实现似乎没有这样做(我认为它们只是默认值)。 我可以重写Equals()
以使用SetEquals()
但是GetHashCode()
呢? 我觉得我在这里错过了一些东西……
您可以使用HashSet
提供的set comparer:
var myDictionary = new Dictionary, TValue>(HashSet.CreateSetComparer());
digEmAll的答案显然是实践中更好的选择,因为它使用内置代码而不是重新发明轮子。 但我会将此作为示例实现。
您可以使用实现使用SetEquals
的IEqualityComparer
。 然后将其传递给Dictionary的构造函数。 像下面的东西(没有测试):
class HashSetEqualityComparer: IEqualityComparer> { public int GetHashCode(HashSet 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 set1, HashSet set2) { if(set1 == set2) return true; if(set1 == null || set2 == null) return false; return set1.SetEquals(set2); } }
请注意,这里的哈希函数是可交换的,这很重要,因为集合中元素的枚举顺序是未定义的。
另一个有趣的一点是,您不能只使用elem.GetHashCode
因为当向集合提供自定义相等比较器时,这会产生错误的结果。
您可以向Dictionary构造函数提供IEqualityComparer
,并在该比较器中进行所需的实现。