1 00:00:06,570 --> 00:00:07,800 - In the previous section, 2 00:00:07,800 --> 00:00:10,260 we looked at a trait called PartialEq. 3 00:00:10,260 --> 00:00:13,740 It finds a method which allows you to compare two objects 4 00:00:13,740 --> 00:00:15,060 for equality. 5 00:00:15,060 --> 00:00:18,723 There's also a trait called Eq, as we can see here. 6 00:00:19,733 --> 00:00:23,242 And Eq inherits from PartialEq, 7 00:00:23,242 --> 00:00:26,070 so it's a bit odd, the way that it works in Rust. 8 00:00:26,070 --> 00:00:29,490 But it's the PartialEq trait 9 00:00:29,490 --> 00:00:33,780 which actually defines the methods for equality, 10 00:00:33,780 --> 00:00:35,520 and not equality. 11 00:00:35,520 --> 00:00:40,353 And then inheriting from it, we have this trait called Eq. 12 00:00:41,790 --> 00:00:43,800 Okay, so bear with me. 13 00:00:43,800 --> 00:00:45,750 I've called it a marker trait. 14 00:00:45,750 --> 00:00:49,050 A marker trait is one that doesn't have any methods. 15 00:00:49,050 --> 00:00:53,070 So there aren't any new methods in the Eq trait. 16 00:00:53,070 --> 00:00:57,210 It's almost like a compiler flag, to say that my type, 17 00:00:57,210 --> 00:01:02,210 you could have a type here which implements the Eq trait, 18 00:01:02,310 --> 00:01:04,920 and therefore obviously it would also have to implement 19 00:01:04,920 --> 00:01:06,963 the PartialEq trait as well. 20 00:01:08,280 --> 00:01:09,990 So, this is quite a confusing thing. 21 00:01:09,990 --> 00:01:12,330 Let's discuss what the difference is 22 00:01:12,330 --> 00:01:14,370 between these two traits. 23 00:01:14,370 --> 00:01:15,990 The code is actually very simple. 24 00:01:15,990 --> 00:01:18,570 It's understanding the application of the concept 25 00:01:18,570 --> 00:01:19,820 is the interesting thing. 26 00:01:20,730 --> 00:01:25,413 So, the Eq trait inherits the Eq method, 27 00:01:26,280 --> 00:01:28,713 for equality tests, from PartialEq. 28 00:01:29,880 --> 00:01:32,280 And also implements, or inherits, I should say, 29 00:01:32,280 --> 00:01:35,880 the NE, not equals, it inherits that method, 30 00:01:35,880 --> 00:01:38,460 for not equals tests, from there as well, 31 00:01:38,460 --> 00:01:40,893 it doesn't add any new methods at all. 32 00:01:41,910 --> 00:01:43,470 So what's the point of that? 33 00:01:43,470 --> 00:01:45,450 You might be wondering, you could have a type, 34 00:01:45,450 --> 00:01:47,520 imagine you've got a structure, 35 00:01:47,520 --> 00:01:49,923 which just implements PartialEq. 36 00:01:51,030 --> 00:01:53,100 Then you've already got enough 37 00:01:53,100 --> 00:01:57,480 to be able to test for equality and inequality. 38 00:01:57,480 --> 00:02:01,530 Why bother implementing the Eq trait instead? 39 00:02:01,530 --> 00:02:03,300 But what the Eq trait does, 40 00:02:03,300 --> 00:02:06,513 if your structure implements Eq. 41 00:02:07,440 --> 00:02:09,060 I'll just draw that back in again. 42 00:02:09,060 --> 00:02:10,760 If your structure is kind of here. 43 00:02:12,300 --> 00:02:14,970 And it implements the Eq trait. 44 00:02:14,970 --> 00:02:19,140 And therefore obviously also implements PartialEq. 45 00:02:19,140 --> 00:02:22,470 It tells the compiler a little bit more about your type. 46 00:02:22,470 --> 00:02:25,410 Okay, for a type which implements the Eq trait, 47 00:02:25,410 --> 00:02:26,850 the compiler assumes 48 00:02:26,850 --> 00:02:29,460 that you've implemented the equality tests 49 00:02:29,460 --> 00:02:33,090 in such a way that you have equivalence relationships. 50 00:02:33,090 --> 00:02:36,150 There are three extra things the compiler can assume 51 00:02:36,150 --> 00:02:38,940 if your type equal implements Eq, 52 00:02:38,940 --> 00:02:41,460 rather than just PartialEq. 53 00:02:41,460 --> 00:02:45,630 So if your structure here implements the Eq trait, 54 00:02:45,630 --> 00:02:50,220 the compiler assumes that you have reflexivity. 55 00:02:50,220 --> 00:02:52,080 You can say X equals X. 56 00:02:52,080 --> 00:02:53,670 It means, basically, 57 00:02:53,670 --> 00:02:56,610 the compiler couldn't know this unless you tell it. 58 00:02:56,610 --> 00:02:59,040 If your type implements the Eq trait, 59 00:02:59,040 --> 00:03:01,380 then the way you've implemented the equality test, 60 00:03:01,380 --> 00:03:05,493 is such that it's okay to compare the object against itself. 61 00:03:06,750 --> 00:03:10,470 It also implies symmetric equivalence. 62 00:03:10,470 --> 00:03:14,400 Okay, so in other words, you've written your equality method 63 00:03:14,400 --> 00:03:19,170 so that if X equals Y, then it assumes that Y also equals X. 64 00:03:19,170 --> 00:03:20,940 So it's symmetric. 65 00:03:20,940 --> 00:03:23,040 And also transitive. 66 00:03:23,040 --> 00:03:26,250 And all of these promises, the compiler assumes, 67 00:03:26,250 --> 00:03:30,420 if your structure implements the equality trait, Eq, 68 00:03:30,420 --> 00:03:33,180 it assumes that you've implemented your logic, 69 00:03:33,180 --> 00:03:38,180 such that it's transitive, and symmetric, and reflexive. 70 00:03:38,340 --> 00:03:40,740 Okay, so it can make optimizations in your code. 71 00:03:41,610 --> 00:03:45,690 Transitive equality is if X is equal to Y, 72 00:03:45,690 --> 00:03:49,500 and Y is equal to Z, then it implies X is equal to Z. 73 00:03:49,500 --> 00:03:51,210 Okay, so it's transitive. 74 00:03:51,210 --> 00:03:54,030 All of these three assumptions the compiler will make 75 00:03:54,030 --> 00:03:56,133 if your structure implements Eq. 76 00:03:57,000 --> 00:04:01,023 On the other hand, if your structure didn't implement Eq, 77 00:04:01,950 --> 00:04:03,650 but it just implemented PartialEq. 78 00:04:05,460 --> 00:04:06,293 Okay? 79 00:04:06,293 --> 00:04:09,960 Then just because X equals Y, 80 00:04:09,960 --> 00:04:12,720 the compiler couldn't assume that you've written the test 81 00:04:12,720 --> 00:04:15,210 so that this would also prove true. 82 00:04:15,210 --> 00:04:16,560 It couldn't assume that. 83 00:04:16,560 --> 00:04:17,760 And it couldn't assume 84 00:04:17,760 --> 00:04:22,760 that if X equals Y then Y also equals X. 85 00:04:23,310 --> 00:04:24,900 And it couldn't assume transitive, 86 00:04:24,900 --> 00:04:29,900 it couldn't assume that because X equals Y, and Y equals Z, 87 00:04:30,630 --> 00:04:34,080 it doesn't necessarily imply that X equals Z, 88 00:04:34,080 --> 00:04:36,900 because you haven't maybe implemented that way, 89 00:04:36,900 --> 00:04:38,310 you haven't told the compiler 90 00:04:38,310 --> 00:04:39,993 that those assumptions are true. 91 00:04:40,830 --> 00:04:43,020 To tell it that these assumptions hold true, 92 00:04:43,020 --> 00:04:45,333 then you implement the Eq trait. 93 00:04:46,901 --> 00:04:47,734 Here. 94 00:04:52,190 --> 00:04:54,810 So it is quite common for you to implement both. 95 00:04:54,810 --> 00:04:57,273 Remember, if you implement a trait, 96 00:04:58,350 --> 00:05:00,960 you must also implement all of its super traits. 97 00:05:00,960 --> 00:05:02,580 So if you implement Eq, 98 00:05:02,580 --> 00:05:05,203 then you must also implement PartialEq, 99 00:05:05,203 --> 00:05:06,690 and it's the PartialEq 100 00:05:06,690 --> 00:05:09,720 which does the actual work of comparison. 101 00:05:09,720 --> 00:05:11,190 I think most Rust developers 102 00:05:11,190 --> 00:05:13,687 scratch their heads at this for a while, thinking, 103 00:05:13,687 --> 00:05:17,667 "That's a really kind of interesting design decision." 104 00:05:19,020 --> 00:05:20,160 But that's what it is. 105 00:05:20,160 --> 00:05:25,160 So, the easiest way to support Eq is just by hash derive. 106 00:05:26,340 --> 00:05:28,320 Because it's a market interface, 107 00:05:28,320 --> 00:05:30,930 because there's no actual method to implement. 108 00:05:30,930 --> 00:05:35,100 It's just like a stamp, to say, yes, I support this trait. 109 00:05:35,100 --> 00:05:37,470 Then why bother actually implementing it manually? 110 00:05:37,470 --> 00:05:41,910 You just basically mark your structure as implementing, 111 00:05:41,910 --> 00:05:43,440 deriving the Eq support. 112 00:05:43,440 --> 00:05:46,560 You've also, of course, gotta implement PartialEq as well, 113 00:05:46,560 --> 00:05:48,600 because that's a super trait. 114 00:05:48,600 --> 00:05:51,870 So, what I've done here, is I've got a class, 115 00:05:51,870 --> 00:05:54,420 or structure, I should say, called EmpCode. 116 00:05:54,420 --> 00:05:56,370 It represents like a primary key 117 00:05:56,370 --> 00:06:00,120 for an employee and a company, and it's a composite key. 118 00:06:00,120 --> 00:06:03,600 The employee's code contains the country that they work in, 119 00:06:03,600 --> 00:06:07,800 like the UK, and their employee number within that country. 120 00:06:07,800 --> 00:06:10,410 Okay, so it is like a composite key. 121 00:06:10,410 --> 00:06:12,573 It could be that in the UK, 122 00:06:13,938 --> 00:06:16,370 you could have employees one through to 100. 123 00:06:16,370 --> 00:06:19,290 In Singapore, you could have employees one through 100, 124 00:06:19,290 --> 00:06:22,350 you need to know both the country, and the employee number, 125 00:06:22,350 --> 00:06:25,080 to identify, uniquely, an employee. 126 00:06:25,080 --> 00:06:28,380 That's the kind of example I've got. 127 00:06:28,380 --> 00:06:31,770 So, I've derived implementation of Eq. 128 00:06:31,770 --> 00:06:34,500 And I've also derived implementation of PartialEq. 129 00:06:34,500 --> 00:06:37,590 Remember how that works, from the previous section? 130 00:06:37,590 --> 00:06:41,640 If you derive automatic implementation of PartialEq, 131 00:06:41,640 --> 00:06:43,800 the compiler will generate an equality test, 132 00:06:43,800 --> 00:06:46,770 that'll do an equality test on field one, 133 00:06:46,770 --> 00:06:48,840 and an equality test on field two. 134 00:06:48,840 --> 00:06:50,370 So two EmpCodes 135 00:06:50,370 --> 00:06:54,510 that had the same country and employee number as strings 136 00:06:54,510 --> 00:06:55,650 would compare equal. 137 00:06:55,650 --> 00:06:58,080 That's the PartialEq implementation. 138 00:06:58,080 --> 00:07:00,630 And the Eq implementation is just a marker 139 00:07:00,630 --> 00:07:03,930 to say it's transitive, reflexive, and symmetric. 140 00:07:03,930 --> 00:07:07,890 So it's really easy to actually implement the Eq trait, 141 00:07:07,890 --> 00:07:09,590 once you understand what it's for. 142 00:07:10,440 --> 00:07:13,230 Now then, if you implement the Eq trait, 143 00:07:13,230 --> 00:07:16,890 you might also want to implement another trait called hash. 144 00:07:16,890 --> 00:07:21,030 This is quite common in languages like C#, and Java, 145 00:07:21,030 --> 00:07:22,890 where you have like an equals method, 146 00:07:22,890 --> 00:07:24,330 and when you implement equals, 147 00:07:24,330 --> 00:07:25,650 you typically also implement 148 00:07:25,650 --> 00:07:28,650 some kind of get hash code method as well. 149 00:07:28,650 --> 00:07:32,010 So if your structure implements hash 150 00:07:32,010 --> 00:07:35,640 then your structure can be inserted into a hash set. 151 00:07:35,640 --> 00:07:38,760 A hash set has unique collections. 152 00:07:38,760 --> 00:07:40,950 A collection of unique elements, I should say. 153 00:07:40,950 --> 00:07:43,800 And when you insert an item into a hash set, 154 00:07:43,800 --> 00:07:45,690 the compiler has to be able to call 155 00:07:45,690 --> 00:07:48,810 some kind of hash algorithm on your object, 156 00:07:48,810 --> 00:07:50,730 to figure out which bucket to put it in, 157 00:07:50,730 --> 00:07:52,590 so it can retrieve it again quickly. 158 00:07:52,590 --> 00:07:56,850 It uses a hashing mechanism to locate items quickly. 159 00:07:56,850 --> 00:07:59,820 So if your structure type implements the hash trait, 160 00:07:59,820 --> 00:08:02,550 then your structure type, like EmpCode, 161 00:08:02,550 --> 00:08:04,920 could be inserted into a hash set. 162 00:08:04,920 --> 00:08:06,690 If it didn't implement hash, 163 00:08:06,690 --> 00:08:08,130 then it couldn't be implemented 164 00:08:08,130 --> 00:08:10,383 and inserted into a hash set. 165 00:08:11,391 --> 00:08:13,440 And the other thing you can do, if you implement hash, 166 00:08:13,440 --> 00:08:17,100 is your type can be used as a key in a hash map. 167 00:08:17,100 --> 00:08:18,510 Okay, you could have a hash map, 168 00:08:18,510 --> 00:08:21,510 where the key type is like employee code. 169 00:08:21,510 --> 00:08:22,890 So you look up the code, 170 00:08:22,890 --> 00:08:24,870 and you get back a value, again, hash key. 171 00:08:24,870 --> 00:08:28,200 When you insert a key value pair into a hash map, 172 00:08:28,200 --> 00:08:30,600 the key is hashed. 173 00:08:30,600 --> 00:08:33,120 It performs some kind of integer algorithm on it 174 00:08:33,120 --> 00:08:35,670 to figure out which bucket to put it in, in memory, 175 00:08:35,670 --> 00:08:38,520 for fast retrieval, for indexing, basically. 176 00:08:38,520 --> 00:08:41,280 So if you want your type to participate in hashing, 177 00:08:41,280 --> 00:08:42,990 then you can implement the hash code, 178 00:08:42,990 --> 00:08:44,400 the hash trait as well. 179 00:08:44,400 --> 00:08:45,720 And that's quite common. 180 00:08:45,720 --> 00:08:47,340 It is quite common to implement 181 00:08:47,340 --> 00:08:51,693 both Eq for equality checking, and hash for hashing. 182 00:08:52,590 --> 00:08:53,880 Right, so again, 183 00:08:53,880 --> 00:08:56,940 the most typical way to support the hash trait 184 00:08:56,940 --> 00:08:58,290 is via derive. 185 00:08:58,290 --> 00:08:59,640 So you get the compiler 186 00:08:59,640 --> 00:09:02,580 to generate an implementation for you. 187 00:09:02,580 --> 00:09:04,020 And this is possible 188 00:09:04,020 --> 00:09:07,920 if each field in your structure implements hash. 189 00:09:07,920 --> 00:09:09,030 Like string. 190 00:09:09,030 --> 00:09:12,993 String implements hash, there's a hash mechanism in strings. 191 00:09:13,860 --> 00:09:17,100 So, the resultant hash of your structure 192 00:09:17,100 --> 00:09:20,871 will be a combination of the hash code for each field. 193 00:09:20,871 --> 00:09:23,550 You don't actually need to worry how it works, internally. 194 00:09:23,550 --> 00:09:25,830 You can override the mechanism if you want to, 195 00:09:25,830 --> 00:09:27,990 but generally this will be sufficient. 196 00:09:27,990 --> 00:09:29,163 So it looks like this. 197 00:09:30,000 --> 00:09:33,240 Here is my revamped EmpCode structure. 198 00:09:33,240 --> 00:09:37,590 And the key point here, ah, the key point, no pun intended, 199 00:09:37,590 --> 00:09:40,440 is that my EmpCode supports hashing. 200 00:09:40,440 --> 00:09:43,050 So I could insert, I could use EmpCode, 201 00:09:43,050 --> 00:09:46,380 as the key type, in a hash map, bear that in mind. 202 00:09:46,380 --> 00:09:50,250 I can also check for equality using PartialEq. 203 00:09:50,250 --> 00:09:53,400 And I can check for equivalence, in other words, 204 00:09:53,400 --> 00:09:58,020 symmetrical, transitive, and reflexive equality as well, 205 00:09:58,020 --> 00:09:59,223 because of the Eq trait. 206 00:10:00,540 --> 00:10:01,530 Right. 207 00:10:01,530 --> 00:10:04,770 So, let's apply all this in an actual example, 208 00:10:04,770 --> 00:10:06,390 going back into our project. 209 00:10:06,390 --> 00:10:07,443 Lesson13_generics. 210 00:10:08,430 --> 00:10:09,930 We'll start off with main. 211 00:10:09,930 --> 00:10:12,420 And then the most interesting part of the demo 212 00:10:12,420 --> 00:10:13,620 will be in demo_eq_hash. 213 00:10:14,490 --> 00:10:16,590 It illustrates the Eq trait, 214 00:10:16,590 --> 00:10:19,170 and the hash trait implementation. 215 00:10:19,170 --> 00:10:20,640 And then of course we'll run the project, 216 00:10:20,640 --> 00:10:21,753 let's have a look. 217 00:10:22,740 --> 00:10:24,290 This is quite exciting I think. 218 00:10:25,530 --> 00:10:26,363 Right, in Main, 219 00:10:26,363 --> 00:10:29,160 well, obviously in a work-related kinda context. 220 00:10:29,160 --> 00:10:31,050 So, that was the previous demo, 221 00:10:31,050 --> 00:10:35,850 and here is my implementation of demo_eq and hash, 222 00:10:35,850 --> 00:10:37,463 let's uncomment that. 223 00:10:38,730 --> 00:10:40,773 And it's here. 224 00:10:42,210 --> 00:10:44,010 So, I've got an EmpCode, 225 00:10:44,010 --> 00:10:47,163 which is like a key to look up an employee. 226 00:10:48,120 --> 00:10:52,050 And I've benefited from off-the-shelf implementation, 227 00:10:52,050 --> 00:10:54,390 isn't this a wonderful mechanism, now? 228 00:10:54,390 --> 00:10:55,980 You can get the compiler 229 00:10:55,980 --> 00:10:59,220 to automatically derive or generate 230 00:10:59,220 --> 00:11:04,220 implementation of the Eq trait, which is a marker trait. 231 00:11:05,070 --> 00:11:09,270 The hash trait, which will basically calculate the hash code 232 00:11:09,270 --> 00:11:12,090 by combining the hash code of the country, 233 00:11:12,090 --> 00:11:14,130 and the hash code of the employee number, 234 00:11:14,130 --> 00:11:17,760 both of them strings, and they both implement hash. 235 00:11:17,760 --> 00:11:20,280 And also, off the shelf, 236 00:11:20,280 --> 00:11:23,220 generated implementation of PartialEq. 237 00:11:23,220 --> 00:11:27,990 It'll generate an Eq, sorry, yeah, an EQ method, 238 00:11:27,990 --> 00:11:31,650 and an NE method, based on equality checks 239 00:11:31,650 --> 00:11:33,960 for the countries of two objects. 240 00:11:33,960 --> 00:11:38,190 And the empnum values for two EmpCode objects. 241 00:11:38,190 --> 00:11:40,980 And if those two values are equal, 242 00:11:40,980 --> 00:11:45,290 if my EmpCode number one, country and emp number, 243 00:11:45,290 --> 00:11:49,200 is the same as EmpCode number two, country and emp number, 244 00:11:49,200 --> 00:11:50,997 then those two objects would be deemed equal, 245 00:11:50,997 --> 00:11:54,123 and that's the default implementation provided there. 246 00:11:55,530 --> 00:11:58,080 So that's like a composite key type in a database, 247 00:11:58,080 --> 00:12:00,720 that's the kind of image to have in mind. 248 00:12:00,720 --> 00:12:03,240 In terms of implementation, all I've done 249 00:12:03,240 --> 00:12:06,060 is to just implement an associated new function, 250 00:12:06,060 --> 00:12:07,440 just to create an instance, 251 00:12:07,440 --> 00:12:09,780 this is quite common now, we've seen this a lot, haven't we? 252 00:12:09,780 --> 00:12:13,890 I pass in a atring slice for the country code. 253 00:12:13,890 --> 00:12:18,540 And a string slice for the employee number, like 007. 254 00:12:18,540 --> 00:12:20,283 And it returns an EmpCode. 255 00:12:21,150 --> 00:12:23,730 It returns an EmpCode whose country field 256 00:12:23,730 --> 00:12:28,730 is a stringification of the incoming country as a slice. 257 00:12:28,770 --> 00:12:31,593 So that means I can pass in a string literal, remember. 258 00:12:33,077 --> 00:12:34,290 And the employee number as well. 259 00:12:34,290 --> 00:12:37,290 So that EmpCode is gonna be constructed. 260 00:12:37,290 --> 00:12:41,970 So EmpCode taken together is kind of like my composite key. 261 00:12:41,970 --> 00:12:44,760 I'm gonna use that as a key type in the dictionary. 262 00:12:44,760 --> 00:12:47,880 Let me show you that, actually, in my code down here. 263 00:12:47,880 --> 00:12:52,880 In my duet code, I've created a collection, 264 00:12:53,700 --> 00:12:57,970 a hash map, where the key is EmpCode. 265 00:12:57,970 --> 00:13:01,800 Okay, now I can only use EmpCode as a key type, 266 00:13:01,800 --> 00:13:04,593 because EmpCode implements hash. 267 00:13:06,420 --> 00:13:08,730 If EmpCode didn't implement hash, 268 00:13:08,730 --> 00:13:11,880 then I couldn't use EmpCode as the key type. 269 00:13:11,880 --> 00:13:14,970 You can only use hashable types as the key. 270 00:13:14,970 --> 00:13:16,773 So you'd look up an EmpCode, 271 00:13:17,640 --> 00:13:20,730 and you'd get back the employee who has that code. 272 00:13:20,730 --> 00:13:22,860 I've got an emp structure as well. 273 00:13:22,860 --> 00:13:24,030 So let's have look at the emp structure, 274 00:13:24,030 --> 00:13:27,870 this is the value type in my hash map. 275 00:13:27,870 --> 00:13:30,810 So an employee has a name and a salary. 276 00:13:30,810 --> 00:13:34,650 Oh, only a 32-bit salary, okay. 277 00:13:34,650 --> 00:13:36,450 Not as large as it might be then. 278 00:13:36,450 --> 00:13:39,540 Oh, and also, I've got debug support built in. 279 00:13:39,540 --> 00:13:40,620 Again, that's quite handy, 280 00:13:40,620 --> 00:13:43,590 I can just output an employee using the debug formatter 281 00:13:43,590 --> 00:13:46,540 and it'll automatically just output the name in the salary. 282 00:13:47,490 --> 00:13:49,863 Do I have any implementation for my employee? 283 00:13:51,210 --> 00:13:53,160 Okay, just the constructor, basically, 284 00:13:53,160 --> 00:13:56,130 just to basically create a new employee instance, 285 00:13:56,130 --> 00:13:58,140 with a given name and salary. 286 00:13:58,140 --> 00:14:01,140 So not a lot going on there, it's a fairly simple data type. 287 00:14:02,160 --> 00:14:06,030 Okay, so, staff is my hash map. 288 00:14:06,030 --> 00:14:08,250 Here's my mutable hash map, 289 00:14:08,250 --> 00:14:10,380 which contains an EmpCode as the key, 290 00:14:10,380 --> 00:14:13,350 and an employee as the value, empty initially. 291 00:14:13,350 --> 00:14:14,940 I can insert. 292 00:14:14,940 --> 00:14:19,320 This will create an employee code UK 001, 293 00:14:19,320 --> 00:14:22,200 so country code, employee number. 294 00:14:22,200 --> 00:14:25,530 In the UK, this is employee number 001. 295 00:14:25,530 --> 00:14:29,703 And it's Matt and he earns 1000, 1000 units of salary. 296 00:14:30,630 --> 00:14:35,433 And I've inserted, into the UK, employee number two is Mark. 297 00:14:36,420 --> 00:14:40,470 And then, I've also inserted, in the US, 298 00:14:40,470 --> 00:14:43,710 employee 001 in the US is Mary. 299 00:14:43,710 --> 00:14:48,710 Notice that the employee number is the same as here. 300 00:14:49,590 --> 00:14:52,770 But this was for a UK-based employee, 301 00:14:52,770 --> 00:14:55,020 and this is for a US-based employee. 302 00:14:55,020 --> 00:14:56,070 So they're different. 303 00:14:57,683 --> 00:15:01,740 And then I do a lookup, I say in my staff, lookup, 304 00:15:01,740 --> 00:15:03,220 I create an EmpCode. 305 00:15:04,170 --> 00:15:07,020 I create an EmpCode, this is the key that I'm gonna look up, 306 00:15:07,020 --> 00:15:10,050 look up in my hash map. 307 00:15:10,050 --> 00:15:11,130 Look up. 308 00:15:11,130 --> 00:15:13,080 That's the employee code. 309 00:15:13,080 --> 00:15:15,813 I'm gonna look up employee 002. 310 00:15:16,980 --> 00:15:18,600 It takes a reference, 311 00:15:18,600 --> 00:15:20,010 so you have to give it a reference here, 312 00:15:20,010 --> 00:15:23,760 the ampersand there, it borrows that EmpCode value. 313 00:15:23,760 --> 00:15:26,310 And I'm hoping it'll give me back 314 00:15:26,310 --> 00:15:28,773 which employee has EmpCode 002. 315 00:15:29,760 --> 00:15:32,730 I'm hoping it's going to be giving me back this value here. 316 00:15:32,730 --> 00:15:36,960 So I'm hoping this will return back a reference to Mark. 317 00:15:36,960 --> 00:15:39,690 Okay, I'm gonna output Mark using the debugger. 318 00:15:39,690 --> 00:15:41,310 That's what I should see. 319 00:15:41,310 --> 00:15:42,783 Okay, so let's run it then. 320 00:15:51,150 --> 00:15:53,580 Okay, so quite a lot going on. 321 00:15:53,580 --> 00:15:55,140 Of course, the only output that we see, 322 00:15:55,140 --> 00:15:58,867 is that we've successfully looked up UK-based employee 002, 323 00:15:59,760 --> 00:16:02,610 using this kind of composite key approach, 324 00:16:02,610 --> 00:16:05,580 which implements hashing, and equality checks. 325 00:16:05,580 --> 00:16:10,580 And it'll give me back employee Mark, with a salary of 2K. 326 00:16:10,590 --> 00:16:11,423 Fantastic.