1 00:00:00,390 --> 00:00:01,700 In the previous video, 2 00:00:01,700 --> 00:00:06,048 we got this compiler warning when we overrode object.equals in the Point class. 3 00:00:06,048 --> 00:00:11,080 TreehouseDefense.Point overrides Object.Equals but 4 00:00:11,080 --> 00:00:15,010 it does not override Object.GetHashCode. 5 00:00:15,010 --> 00:00:19,000 The hash code of an object is an integer that is unique to that object. 6 00:00:19,000 --> 00:00:22,020 Different objects will have different hash codes. 7 00:00:22,020 --> 00:00:24,880 Every object created is given a unique identifier. 8 00:00:24,880 --> 00:00:29,260 So by default, this ID is used as an object's hash code. 9 00:00:29,260 --> 00:00:33,850 This ID, if you will, is actually just its memory address. 10 00:00:33,850 --> 00:00:38,200 Being able to identify an object by its hash code is very handy and 11 00:00:38,200 --> 00:00:42,210 the GetHashCode method is used by many C# collection types. 12 00:00:42,210 --> 00:00:45,100 An array is just one type of collection. 13 00:00:45,100 --> 00:00:48,340 There are other types of collection classes that rely on being able to 14 00:00:48,340 --> 00:00:51,010 identify an object using just an integer. 15 00:00:51,010 --> 00:00:55,511 The most common collection that uses the GetHashCode method is .NET framework's 16 00:00:55,511 --> 00:00:57,248 dictionary class. 17 00:00:57,248 --> 00:01:02,580 A hash code is only an attempt to create a unique identifier for an object. 18 00:01:02,580 --> 00:01:06,370 It is possible for two different objects to have the same hash code. 19 00:01:06,370 --> 00:01:11,110 Just like my name is Jeremy but there are also other people named Jeremy. 20 00:01:11,110 --> 00:01:13,150 In fact it's a rather common name. 21 00:01:13,150 --> 00:01:16,350 If someone called out my name in a large crowd, 22 00:01:16,350 --> 00:01:19,360 there's a good chance that more than one person would respond. 23 00:01:19,360 --> 00:01:23,960 How could they know which person is the Jeremy they're looking for? 24 00:01:23,960 --> 00:01:27,330 Well, they'd have to rely on more than just our name. 25 00:01:27,330 --> 00:01:30,260 They'd probably need to get a look at each of us 26 00:01:30,260 --> 00:01:32,720 in order to say which person they wanted. 27 00:01:32,720 --> 00:01:37,780 This is why the methods Equals and GetHashCode go hand in hand. 28 00:01:37,780 --> 00:01:40,780 If two objects map to the same hash code, 29 00:01:40,780 --> 00:01:44,350 the only way to tell them apart is to check if they're equal. 30 00:01:44,350 --> 00:01:47,740 Had we only overridden the GetHashCode method, 31 00:01:47,740 --> 00:01:52,170 we'd get a similar compiler warning asking us to override Equals too. 32 00:01:52,170 --> 00:01:55,830 Let's get a better idea of how the GetHashCode method works 33 00:01:55,830 --> 00:01:57,191 by overriding it in Point. 34 00:02:00,470 --> 00:02:04,651 So we'll type public 35 00:02:04,651 --> 00:02:10,240 override int GetHashCode. 36 00:02:10,240 --> 00:02:14,490 In order to implement GetHashCode, we need to make a couple decisions. 37 00:02:14,490 --> 00:02:18,240 First if two objects are equal as we've defined equality to be up 38 00:02:18,240 --> 00:02:21,910 here should their hash codes also be equal? 39 00:02:21,910 --> 00:02:24,440 We almost always want this to be the case. 40 00:02:24,440 --> 00:02:28,740 And this is what users of the GetHashCode method will expect. 41 00:02:28,740 --> 00:02:34,110 Here we see that we determine if the Point objects are equal by comparing the X and 42 00:02:34,110 --> 00:02:35,980 Y coordinates with each other. 43 00:02:35,980 --> 00:02:39,800 We should also use X and Y when creating the new hash code. 44 00:02:39,800 --> 00:02:44,440 But here's the problem that we always run into when creating hash codes. 45 00:02:44,440 --> 00:02:48,020 We can only return a single integer as the hash code. 46 00:02:48,020 --> 00:02:50,700 Here we have two integers, X and Y. 47 00:02:50,700 --> 00:02:52,570 We can't return them both. 48 00:02:52,570 --> 00:02:55,740 Let's say we just returned X as the hash code. 49 00:02:55,740 --> 00:03:00,830 That means that all points with the same X value would have the same hash code. 50 00:03:00,830 --> 00:03:02,500 That isn't very unique. 51 00:03:02,500 --> 00:03:06,370 Our goal is to create a hash code that is unique as possible. 52 00:03:06,370 --> 00:03:09,770 The best chance we have of doing this is by combining X and 53 00:03:09,770 --> 00:03:12,270 Y, somehow, into a single integer. 54 00:03:13,380 --> 00:03:15,520 There are lots of ways we could do this. 55 00:03:15,520 --> 00:03:17,310 We could just add them together. 56 00:03:17,310 --> 00:03:24,050 If X was five and Y was two we'd end up with a hash code of seven. 57 00:03:24,050 --> 00:03:27,940 There are lots of ways to add two different integers together to get seven. 58 00:03:27,940 --> 00:03:31,200 All of those points would also have the same hash code. 59 00:03:31,200 --> 00:03:36,140 We could reduce those combinations by half just by multiplying X or 60 00:03:36,140 --> 00:03:39,530 Y by a prime number before adding them together. 61 00:03:39,530 --> 00:03:44,770 By doing this we're ensuring that X equals 5, and Y equals 2 62 00:03:44,770 --> 00:03:49,750 gives us a different hash code than X equals 2 and Y equals 5. 63 00:03:49,750 --> 00:03:53,768 So here we'll say return x 64 00:03:56,986 --> 00:04:04,200 Times a relatively small prime number 31, and then add Y. 65 00:04:04,200 --> 00:04:07,160 There are lots of ways to create hash codes, and 66 00:04:07,160 --> 00:04:10,010 they are all compromises of some sort. 67 00:04:10,010 --> 00:04:13,150 For what we're doing this is probably good enough. 68 00:04:13,150 --> 00:04:16,630 I should mention that when computing hash codes it's best to compute them from 69 00:04:16,630 --> 00:04:20,040 the hash codes of the fields that we're combining together. 70 00:04:20,040 --> 00:04:24,160 This is because their hash codes are already fairly unique. 71 00:04:24,160 --> 00:04:31,419 So we should write this as X.GetHashCode * 31 + Y.GetHashCode. 72 00:04:31,419 --> 00:04:37,683 In the case of integers the result is the same since 73 00:04:37,683 --> 00:04:43,360 the hash code of an integer is just its value. 74 00:04:44,690 --> 00:04:47,270 So the hash code of five would be five. 75 00:04:47,270 --> 00:04:49,770 If X and Y were of any other type it 76 00:04:49,770 --> 00:04:52,840 would be important to call their GetHashCode methods. 77 00:04:52,840 --> 00:04:58,240 This is just a good practice to always use GetHashCode when computing a hash code. 78 00:04:58,240 --> 00:05:01,930 We'll learn more about how hash codes are used in other courses 79 00:05:01,930 --> 00:05:05,580 where we use more advanced .NET collection types.