问题描述
我使用的是HashSet的词典在C#来实现图形结构。我与HashSet的元素的唯一一个问题,当HashSet的关键是定制类。在这里,我有:
I am using the HashSet and Dictionary in C# to implement a Graph structure. I have a problem with the uniqueness of hashset elements when the hashset key is a customized class. Here I have:
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中会明白我的顶点独特的方式?
The problem is that when I have same vertexes and I want to add them to the graph, they get duplicated. how can I define a way that the HashSet would understand the uniqueness of my vertexes?
推荐答案
选项:
- 覆盖
等于
和GetHash code
在顶点
(也许点
为简单起见),很可能实施[IEquatable] [1]; T&GT;
作为你去 - 创建你自己的实施
的IEqualityComparer&LT;点&GT;
,并传递到构造函数中的HashSet&LT;点&GT;
- Override
Equals
andGetHashCode
inVertex
(and probablyPoint
for simplicity), quite possibly implement[IEquatable][1]<T>
as you go - Create your own implementation of
IEqualityComparer<Vertex>
and pass that to the constructor of theHashSet<Vertex>
第一种选择可能是最简单的,但我的强烈的建议您点
不可改变第一:可变类型(或类型包含可变类型)不好好哈希键。我可能会使其成为一个结构
,也:
The first option is likely to be the simplest, but I would strongly recommend that you make Point
immutable first: mutable types (or types containing mutable types) don't make good hash keys. I'd probably make it a struct
, too:
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
}
...然后覆盖 GetHash code
和等于
和实施 IEquatable&LT ;&GT;
在顶点
过,如:
... then override GetHashCode
and Equals
and implement IEquatable<>
in Vertex
too, e.g.
// 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);
}
}
这篇关于C# - 定义自定义按键的HashSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!