为什么在调用 GetHashCode() 时具有相同元素 return 个不同值的 HashSet?
Why HashSets with same elements return different values when calling to GetHashCode()?
为什么 HashSet<T>.GetHashCode()
returns 具有相同元素的哈希码不同?
例如:
[Fact]
public void EqualSetsHaveSameHashCodes()
{
var set1 = new HashSet<int>(new [] { 1, 2, 3 } );
var set2 = new HashSet<int>(new [] { 1, 2, 3 } );
Assert.Equal(set1.GetHashCode(), set2.GetHashCode());
}
此测试失败。为什么?
我怎样才能得到我需要的结果? "Equal sets give the same hashcode"
您可以实现自定义 HashSet 来覆盖 GetHashCode 函数,该函数从所有内容生成新的哈希码,如下所示:
public class HashSetWithGetHashCode<T> : HashSet<T>
{
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
foreach (var item in this)
hash = hash * 23 + item.GetHashCode();
return hash;
}
}
}
默认情况下(除非另有特别说明),引用类型只有在引用同一对象时才被视为相等。作为开发人员,您可以覆盖 Equals() 和 GetHashCode() 方法,以便您认为相等的对象 return 对于 Equals 为真,对于 GetHashCode 为相同的 int。
根据您使用的测试框架,将有 CollectionAssert.AreEquivalent() 或对 Assert.Equal 的覆盖,它需要一个比较器。
HashSet<T>
默认情况下没有值相等语义。它具有引用相等语义,因此即使包含的元素相同,两个不同的哈希集也不会相等或具有相同的哈希码。
您需要使用特殊用途 IEqualityComparer<HashSet<int>>
才能获得您想要的行为。您可以自己滚动或使用框架为您提供的默认值:
var hashSetOfIntComparer = HashSet<int>.CreateSetComparer();
//will evaluate to true
var haveSameHash = hashSetOfIntComparer.GetHashCode(set1) ==
hashSetOfIntComparer.GetHashCode(set2);
所以,长话短说:
How can I get the result I need? "Equal sets give the same hashcode"
如果您打算使用 HashSet<T>.GetHashCode()
的默认实现,则不能。您要么使用特殊用途的比较器,要么扩展 HashSet<T>
并覆盖 Equals
和 GetHashCode
以满足您的需要。
为什么 HashSet<T>.GetHashCode()
returns 具有相同元素的哈希码不同?
例如:
[Fact]
public void EqualSetsHaveSameHashCodes()
{
var set1 = new HashSet<int>(new [] { 1, 2, 3 } );
var set2 = new HashSet<int>(new [] { 1, 2, 3 } );
Assert.Equal(set1.GetHashCode(), set2.GetHashCode());
}
此测试失败。为什么?
我怎样才能得到我需要的结果? "Equal sets give the same hashcode"
您可以实现自定义 HashSet 来覆盖 GetHashCode 函数,该函数从所有内容生成新的哈希码,如下所示:
public class HashSetWithGetHashCode<T> : HashSet<T>
{
public override int GetHashCode()
{
unchecked // Overflow is fine, just wrap
{
int hash = 17;
foreach (var item in this)
hash = hash * 23 + item.GetHashCode();
return hash;
}
}
}
默认情况下(除非另有特别说明),引用类型只有在引用同一对象时才被视为相等。作为开发人员,您可以覆盖 Equals() 和 GetHashCode() 方法,以便您认为相等的对象 return 对于 Equals 为真,对于 GetHashCode 为相同的 int。
根据您使用的测试框架,将有 CollectionAssert.AreEquivalent() 或对 Assert.Equal 的覆盖,它需要一个比较器。
HashSet<T>
默认情况下没有值相等语义。它具有引用相等语义,因此即使包含的元素相同,两个不同的哈希集也不会相等或具有相同的哈希码。
您需要使用特殊用途 IEqualityComparer<HashSet<int>>
才能获得您想要的行为。您可以自己滚动或使用框架为您提供的默认值:
var hashSetOfIntComparer = HashSet<int>.CreateSetComparer();
//will evaluate to true
var haveSameHash = hashSetOfIntComparer.GetHashCode(set1) ==
hashSetOfIntComparer.GetHashCode(set2);
所以,长话短说:
How can I get the result I need? "Equal sets give the same hashcode"
如果您打算使用 HashSet<T>.GetHashCode()
的默认实现,则不能。您要么使用特殊用途的比较器,要么扩展 HashSet<T>
并覆盖 Equals
和 GetHashCode
以满足您的需要。