替换 System.Drawing.Point 的 GetHashCode() 方法
Substitute the GetHashCode() Method of System.Drawing.Point
System.Drawing.Point
有一个非常非常糟糕的 GetHashCode
方法,如果你打算用它来描述 Image/Bitmap 中的 'pixels':it is just XOR between the X and Y coordinates.
因此,对于尺寸为 2000x2000 的图像,它具有荒谬的碰撞次数,因为只有对角线中的数字才会具有合适的哈希值。
使用未经检查的乘法创建一个像样的 GetHashCode
方法非常容易,正如一些人已经提到的那样 here。
但是如何在 HashSet
中使用这个改进的 GetHashCode
方法?
我知道我可以创建自己的 class/struct MyPoint
并使用这种改进的方法来实现它,但是我会破坏项目中使用 System.Drawing.Point
.[= 的所有其他代码片段28=]
是否可以使用某种扩展方法或类似方法 "overwrite" 来自 System.Drawing.Point
的方法?还是要"tell" HashSet
使用另一个函数代替GetHashCode
?
目前我正在使用带有自定义 IComparer<Point>
的 SortedSet<System.Drawing.Point>
来存储我的积分。当我想知道集合是否包含点时,我调用 BinarySearch
。它比具有 10000 次碰撞的集合中的 HashSet<System.Drawing.Point>.Contains
方法更快,但它不如具有良好哈希的 HashSet
快。
您可以创建自己的 class 来实现 IEqualityComparer<Point>
, then give that class to the 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());
}
}
System.Drawing.Point
有一个非常非常糟糕的 GetHashCode
方法,如果你打算用它来描述 Image/Bitmap 中的 'pixels':it is just XOR between the X and Y coordinates.
因此,对于尺寸为 2000x2000 的图像,它具有荒谬的碰撞次数,因为只有对角线中的数字才会具有合适的哈希值。
使用未经检查的乘法创建一个像样的 GetHashCode
方法非常容易,正如一些人已经提到的那样 here。
但是如何在 HashSet
中使用这个改进的 GetHashCode
方法?
我知道我可以创建自己的 class/struct MyPoint
并使用这种改进的方法来实现它,但是我会破坏项目中使用 System.Drawing.Point
.[= 的所有其他代码片段28=]
是否可以使用某种扩展方法或类似方法 "overwrite" 来自 System.Drawing.Point
的方法?还是要"tell" HashSet
使用另一个函数代替GetHashCode
?
目前我正在使用带有自定义 IComparer<Point>
的 SortedSet<System.Drawing.Point>
来存储我的积分。当我想知道集合是否包含点时,我调用 BinarySearch
。它比具有 10000 次碰撞的集合中的 HashSet<System.Drawing.Point>.Contains
方法更快,但它不如具有良好哈希的 HashSet
快。
您可以创建自己的 class 来实现 IEqualityComparer<Point>
, then give that class to the 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());
}
}