复杂类型的HashSet ExceptWith
本文关键字:ExceptWith HashSet 类型 复杂 | 更新日期: 2023-09-27 18:04:08
我有自定义类的HashSet:
public class Vertex
{
public string Name;
public override bool Equals(object obj)
{
var vert = obj as Vertex;
if (vert !=null)
{
return Name.Equals(vert.Name, StringComparison.InvariantCulture);
}
return false;
}
}
现在我有两个哈希集
HashSet<Vertex> hashSet1 = new HashSet<Vertex>();
HashSet<Vertex> hashSet1 = new HashSet<Vertex>();
现在我想在hashSet1中只有不在hashSet2中的顶点所以我使用ExceptWith方法
hashSet1.ExceptWith(hashSet2);
但这不起作用。我想这行不通,因为我有复杂类型。问题是:是否有一些接口需要在顶点类中实现才能使它工作?我知道,虽然创建HashSet我可以传递一个EqualityComparer,但在我看来,在顶点类中实现一些比较接口方法会更优雅。
是可能的还是我真的不明白?
谢谢。
当覆盖Equals
时,您也应该覆盖GetHashCode
。HashSet
(和其他哈希结构,如Dictionary
)将首先计算一个哈希码为您的对象在一个结构中定位,然后与Equals
比较元素。
public override int GetHashCode()
{
return StringComparer.InvariantCulture.GetHashCode(this.Name);
}
您不必实现任何接口(尽管鼓励使用IEquatable<T>
)。当您在不指定相等比较器的情况下创建哈希集时,默认使用EqualityComparer<T>.Default
,它要求对象本身相互比较(特殊大小写空引用)。
然而,在你的情况下,你的平等契约被打破,因为你没有覆盖GetHashCode
。下面是我如何修改你的字体:
public class Vertex : IEquatable<Vertex>
{
public string Name { get; private set; }
public Vertex(string name)
{
Name = name;
}
public override int GetHashCode()
{
return StringComparer.InvariantCulture.GetHashCode(Name);
}
public override bool Equals(object obj)
{
return Equals(obj as Vertex);
}
public bool Equals(Vertex obj)
{
return obj != null && StringComparer.InvariantCulture.Equals(Name, obj.Name);
}
}
你介意覆盖.GetHashCode()
吗?
你必须用Equals
覆盖来覆盖GetHashCode
。
对象。=方法:
覆盖Equals(Object)的类型也必须覆盖GetHashCode;否则,哈希表可能无法正常工作。