如果您打算使用它来描述图像/位图中的“像素”,System.Drawing.Point有一个非常非常糟糕的GetHashCode方法:
it is just XOR between the X and Y coordinates.
因此,对于具有2000×2000大小的图像,它具有荒谬的分数,因为只有对角线中的数字才具有相当好的散列.
有些人已经提到了here,使用未经检查的乘法创建一个像样的GetHashCode方法非常容易.
但是,如何在HashSet中使用这个改进的GetHashCode方法呢?
我知道我可以创建自己的类/结构MyPoint并使用这些改进的方法实现它,但是我会破坏我的项目中使用System.Drawing.Point的所有其他代码片段.
是否可以使用某种扩展方法等从System.Drawing.Point“覆盖”该方法?或者“告诉”HashSet使用另一个函数而不是GetHashCode?
目前我正在使用SortedSet< System.Drawing.Point>使用自定义IComparer< Point>存储我的积分.当我想知道集合是否包含Point时,我会调用BinarySearch.它比一个HashSet<快; System.Drawing.Point>在一组具有10000个colisions.载有方法,但它没有一样快HashSet的一个好的哈希可能.
解决方法
您可以创建自己的类来实现
IEqualityComparer<Point>
,然后将该类提供给
HashSet
constructor.
例:
public class MyPointEqualityComparer : IEqualityComparer<Point> { public bool Equals(Point p1,Point p2) { return p1 == p2; // defer to Point's existing operator== } public int GetHashCode(Point obj) { return /* your favorite hashcode function here */; } } class Program { static void Main(string[] args) { // Create hashset with custom hashcode algorithm HashSet<Point> myHashSet = new HashSet<Point>(new MyPointEqualityComparer()); // Same thing also works for dictionary Dictionary<Point,string> myDictionary = new Dictionary<Point,string>(new MyPointEqualityComparer()); } }