How can I create a hash code for a custom data structure?

I created the usual data structure "Coordinates", which determines the position of an object in accordance with a specific system.

The coordinate is defined as follows:

public class Coordinate { public int X; public int Y; private int face; public int Face { get { return face; } set { if (value >= 6 | value < 0) throw new Exception("Invalid face number"); else face = value; } } private int shell; public int Shell { get { return shell; } set { if (value < 0) throw new Exception("No negative shell value allowed"); else shell = value; } } public Coordinate(int face, int x, int y, int shell) { this.X = x; this.Y = y; this.face = face; this.shell = shell; } public static Coordinate operator +(Coordinate a, Coordinate b) { return new Coordinate(a.Face + b.Face, aX + bX, aY + bY, a.Shell + b.Shell); } public override bool Equals(object obj) { Coordinate other = (obj as Coordinate); if (other == null) return false; else return (Face == other.Face && Shell == other.Shell && X == other.X && Y == other.Y); } } 

Or, to summarize, it contains int Face (0 to 5), int X, int Y, and int Shell. X, Y and Shell are all linked lower at 0 (inclusive).

I have no experience with hash codes. I need to compare them to make sure they are equal. I tried this:

 private const int MULTIPLIER = 89; [...] int hashCode = 1; hashCode = MULTIPLIER * hashCode + obj.X.GetHashCode(); hashCode = MULTIPLIER * hashCode + obj.Y.GetHashCode(); hashCode = MULTIPLIER * hashCode + obj.Face.GetHashCode(); hashCode = MULTIPLIER * hashCode + obj.Shell.GetHashCode(); return hashCode; 

Having let go of something that I found during Google. But when I try to compile the code using this method, I am sure that it encountered conflicts, since it never ends. Probably falling into all kinds of random loops, thinking that the heap of coordinates is the same or some.

I am sorry that this question is rather elementary, but for some reason I am at a dead end. I'm just looking for advice on how to write this hash code so that it doesn't collide.

+6
source share
2 answers

If this is not the best way, this may be a good enough approach:

 public override int GetHashCode() { return string.Format("{0}-{1}-{2}-{3}", X, Y, Face, Shell).GetHashCode(); } 

Update: Take a look at this article: http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/

+11
source

Basically, when writing hashcode functions, you should make sure that:

  • you do not have obsolete hash codes (i.e. the state of the object should not change after generating the hash code, so the hash code will change if it has been regenerated)
  • objects with equal values ​​return the same hash codes
  • the same object always returns the same hash code (if not changed) - deterministic

It is also great, but not necessary, if:

  • your hash codes are evenly distributed over the possible values ​​(source: Wikipedia )

You do not need to guarantee that different objects return different hash codes. He only frowned because he could slow down the performance of things like Hashtables (if you have a lot of collisions).

However, if you still want your hashcode function to return unique values, you want to know about perfect hashing .

+2
source

Source: https://habr.com/ru/post/900260/


All Articles