我使用C#中的HashSet和Dictionary来实现一个Graph结构.当哈希集密钥是自定义类时,我有一个哈希集元素的唯一性问题.在这里我有
public class Point { public int x { get; set; } public int y { get; set; } } public class Vertex { public Vertex(Point point) { VertexLabel = point; } public Point VertexLabel { get; private set; } } public class Edge { public Edge(Vertex to,Vertex from,double weight) { FromVertex = from; ToVertex = to; Weight = weight; } public Vertex FromVertex { get; private set; } public Vertex ToVertex { get; private set; } public double Weight { get; private set; } } public class Graph { public Graph() { _Vertexes = new HashSet<Vertex>(); _VertexEdgeMapping = new Dictionary<Vertex,LinkedList<Edge>>(); } private HashSet<Vertex> _Vertexes; private Dictionary<Vertex,LinkedList<Edge>> _VertexEdgeMapping; }
问题是,当我有相同的顶点,我想将它们添加到图形,它们被重复.我如何定义一个方法,HashSet将会理解我的顶点的唯一性?
解决方法
选项:
>在顶点中覆盖Equals和GetHashCode(并且为了简单起见可能是Point),很可能实现[IEquatable] [1]< T>当你去时
>创建自己的实现IEqualityComparer< Vertex>并将其传递给HashSet< Vertex>的构造函数
第一个选项可能是最简单的,但我强烈建议您使Point不可变的第一个:可变类型(或包含可变类型的类型)不会产生好的散列键.我也可能会使它成为一个结构体:
public struct Point : IEquatable<Point> { private readonly int x,y; public int X { get { return x; } } public int Y { get { return y; } } public Point(int x,int y) { this.x = x; this.y = y; } public override int GetHashCode() { return 31 * x + 17 * y; // Or something like that } public override bool Equals(object obj) { return obj is Point && Equals((Point) obj); } public bool Equals(Point p) { return x == p.x && y == p.y; } // TODO: Consider overloading the == and != operators }
…然后覆盖GetHashCode和Equals并实现IEquatable<>在顶点也可以.
// Note: sealed to avoid oddities around equality and inheritance public sealed class Vertex : IEquatable<Vertex> { public Vertex(Point point) { VertexLabel = point; } public Point VertexLabel { get; private set; } public override int GetHashCode() { return VertexLabel.GetHashCode(); } public override bool Equals(object obj) { return Equals(obj as Vertex); } public bool Equals(Vertex vertex) { return vertex != null && vertex.VertexLabel.Equals(VertexLabel); } }