System.Drawing.Point
has a really, really bad GetHashCode
method if you intend to use it to describes 'pixels' in a Image/Bitmap: it is just XOR between the X and Y coordinates.
So for a image with, say, 2000x2000 size, it has an absurd number of colisions, since only the numbers in the diagonal are going to have a decent hash.
It's quite easy to create a decent GetHashCode
method using unchecked multiplication, as some people already mentioned here.
But what can I do to use this improved GetHashCode
method in a HashSet
?
I know I could create my own class/struct MyPoint
and implement it using this improved methods, but then I'd break all other pieces of code in my project that use a System.Drawing.Point
.
Is it possible to "overwrite" the method from System.Drawing.Point
using some sort of extension method or the like? Or to "tell" the HashSet
to use another function instead of the GetHashCode
?
Currently I'm using a SortedSet<System.Drawing.Point>
with a custom IComparer<Point>
to store my points. When I want to know if the set contains a Point I call BinarySearch
. It's faster than a HashSet<System.Drawing.Point>.Contains
method in a set with 10000 colisions, but it's no as fast as HashSet
with a good hash could be.
You can create your own class that implements IEqualityComparer<Point>
, then give that class to the HashSet
constructor.
Example:
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());
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With