【问题标题】:Substitute the GetHashCode() Method of System.Drawing.Point替换 System.Drawing.Point 的 GetHashCode() 方法
【发布时间】:2015-08-08 17:52:03
【问题描述】:

System.Drawing.Point 有一个非常非常糟糕的 GetHashCode 方法,如果您打算用它来描述图像/位图中的“像素”:it is just XOR between the X and Y coordinates.

因此,对于尺寸为 2000x2000 的图像,它的 colisions 数量非常荒谬,因为只有对角线中的数字才会有不错的哈希值。

正如一些人已经提到的here,使用未经检查的乘法创建一个体面的GetHashCode 方法非常容易。

但是我该怎么做才能在HashSet 中使用这种改进的GetHashCode 方法? 我知道我可以创建自己的类/结构 MyPoint 并使用这种改进的方法实现它,但是我会破坏我的项目中使用 System.Drawing.Point 的所有其他代码。

是否可以使用某种扩展方法等“覆盖”System.Drawing.Point 中的方法?还是“告诉”HashSet 使用另一个函数而不是 GetHashCode

目前我使用SortedSet<System.Drawing.Point> 和自定义IComparer<Point> 来存储我的积分。当我想知道该集合是否包含一个点时,我调用BinarySearch。它比 HashSet<System.Drawing.Point>.Contains 方法在具有 10000 个 colisions 的集合中更快,但它不如 HashSet 具有良好的哈希值。

【问题讨论】:

    标签: c# performance gdi+ gethashcode


    【解决方案1】:

    您可以创建自己的实现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());
        }
    }
    

    【讨论】:

    • 太棒了!我没有注意到 IEqualityComparer 有一个 GetHashCode() 方法!完美答案!
    猜你喜欢
    • 1970-01-01
    • 2010-10-20
    • 2018-01-25
    • 2011-09-05
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    • 2018-12-11
    相关资源
    最近更新 更多