1 00:00:00,000 --> 00:00:04,731 [MUSIC] 2 00:00:04,731 --> 00:00:05,510 Hi. 3 00:00:05,510 --> 00:00:07,470 I'm Craig and I'm a developer. 4 00:00:07,470 --> 00:00:08,510 Now we've all been there. 5 00:00:08,510 --> 00:00:11,450 We think we understand the basics of a programming language and 6 00:00:11,450 --> 00:00:14,270 then we encounter a line of code that blows our mind. 7 00:00:14,270 --> 00:00:18,320 And it makes us question everything we thought we knew up until that point. 8 00:00:18,320 --> 00:00:21,600 Well a huge culprit of that sort of experience is strings in Java. 9 00:00:23,090 --> 00:00:26,273 Strings have several characteristics about them that, when combined, 10 00:00:26,273 --> 00:00:28,390 can definitely go cross-eyed with confusion. 11 00:00:28,390 --> 00:00:30,730 And you'll find yourself not alone in your confusion. 12 00:00:30,730 --> 00:00:34,170 Hitting the search engines, you'll find hundreds of thousands of questions about 13 00:00:34,170 --> 00:00:35,705 them and why they behave the way they do. 14 00:00:35,705 --> 00:00:39,157 I thought that this format would be a good way to go and 15 00:00:39,157 --> 00:00:42,228 explore why strings seem to be so mysterious. 16 00:00:42,228 --> 00:00:43,281 And try to demystify and 17 00:00:43,281 --> 00:00:46,865 expose the common misunderstandings that happen when we use string in our code. 18 00:00:46,865 --> 00:00:48,605 Are you ready? 19 00:00:48,605 --> 00:00:49,105 Let's dive in. 20 00:00:50,405 --> 00:00:52,235 Okay. So I've written a little program here 21 00:00:52,235 --> 00:00:53,950 called Thing.java. 22 00:00:53,950 --> 00:00:57,150 And it's gonna help us explore some concepts about strings. 23 00:00:57,150 --> 00:01:00,220 Now I've added a method here called explore. 24 00:01:00,220 --> 00:01:03,970 And it takes an assumption about what we are going to be exploring and 25 00:01:03,970 --> 00:01:04,980 an expression. 26 00:01:04,980 --> 00:01:07,080 The expression is expected to always be true. 27 00:01:07,080 --> 00:01:10,100 It will generate a result and let us know if our assumption is correct. 28 00:01:11,110 --> 00:01:13,690 So let's get right into some of those explorations. 29 00:01:13,690 --> 00:01:16,260 We have explored equality a little bit already. 30 00:01:16,260 --> 00:01:19,630 And we know that when we want to compare primitives together we can use the double 31 00:01:19,630 --> 00:01:20,780 equal sign. 32 00:01:20,780 --> 00:01:22,540 So let's make a couple primitives. 33 00:01:22,540 --> 00:01:30,350 So we'll have int firstNumber equals 12 and int secondNumber equals 12. 34 00:01:30,350 --> 00:01:32,703 Hey, let's go ahead and call our explorer method. 35 00:01:32,703 --> 00:01:33,670 That's what it looks like. 36 00:01:33,670 --> 00:01:39,053 We say primitives use double equals. 37 00:01:39,053 --> 00:01:41,849 Okay, and then the expression that we wanna say, 38 00:01:41,849 --> 00:01:45,520 wanna say is firstNumber use double equals to the secondNumber. 39 00:01:47,070 --> 00:01:49,130 All right, well let's just run this and 40 00:01:49,130 --> 00:01:51,624 make sure that our explorer method's working. 41 00:01:51,624 --> 00:01:53,850 So we'll say clear and then javac. 42 00:01:53,850 --> 00:01:57,710 We compile Thing.Java, and then we're gonna run it. 43 00:01:59,290 --> 00:02:00,010 Cool. 44 00:02:00,010 --> 00:02:00,670 So we get a yea. 45 00:02:00,670 --> 00:02:02,080 So we know that it's working. 46 00:02:02,080 --> 00:02:04,780 So that's primitives, but what about objects? 47 00:02:04,780 --> 00:02:07,680 Let's create two brand new objects exactly the same way. 48 00:02:07,680 --> 00:02:11,460 Now since we didn't change anything, they must be equal, right? 49 00:02:11,460 --> 00:02:13,120 So, let's make two new objects. 50 00:02:13,120 --> 00:02:17,130 We'll say Object, firstObject equals new Object. 51 00:02:17,130 --> 00:02:22,860 And secondObject equals new Object. 52 00:02:26,420 --> 00:02:28,160 Okay, so let's explore that. 53 00:02:28,160 --> 00:02:36,572 Well let's say, explore objects work just like primitives. 54 00:02:36,572 --> 00:02:38,876 So we should be able to use the double equals, right? 55 00:02:38,876 --> 00:02:43,526 [BLANK_AUDIO] 56 00:02:43,526 --> 00:02:44,470 Let's run that. 57 00:02:45,700 --> 00:02:47,210 Okay, and we got a what. 58 00:02:47,210 --> 00:02:49,230 you're assumption is incorrect. 59 00:02:49,230 --> 00:02:50,600 Our first what. 60 00:02:50,600 --> 00:02:52,090 So objects work a little bit different. 61 00:02:52,090 --> 00:02:56,780 When we create an object, the variable represents an object reference. 62 00:02:56,780 --> 00:03:00,820 Now you can use double equals for objects, but what that's saying is that 63 00:03:00,820 --> 00:03:05,020 the object references are actually referring to the same object. 64 00:03:05,020 --> 00:03:05,940 Let's explore that. 65 00:03:05,940 --> 00:03:08,370 So, first of all, let's fix our exploration statement here, 66 00:03:08,370 --> 00:03:16,010 our assumption, and let's say, Objects, references use double equals to check 67 00:03:16,010 --> 00:03:21,270 if they refer to the same object in memory. 68 00:03:21,270 --> 00:03:28,120 It's gonna wrap seemingly equal objects are not equal. 69 00:03:28,120 --> 00:03:30,800 So we can actually use the not equals sign. 70 00:03:31,870 --> 00:03:32,410 So let's do that. 71 00:03:33,450 --> 00:03:38,340 I know, let's go ahead and make a new object that refers to the first object. 72 00:03:38,340 --> 00:03:43,470 So we'll just say Object, the sameObject equals, and 73 00:03:43,470 --> 00:03:47,280 we'll just literally put the object reference in there. 74 00:03:47,280 --> 00:03:49,110 So now let's ex, let's do another exploration. 75 00:03:49,110 --> 00:03:54,068 Let's say, let's say explore object references 76 00:03:54,068 --> 00:03:59,030 must refer to the same object to use double equals. 77 00:04:02,800 --> 00:04:05,947 So, firstObject equals sameObject. 78 00:04:05,947 --> 00:04:10,060 Let's go ahead and run that and see. 79 00:04:10,060 --> 00:04:11,940 There we go, two YAYs. 80 00:04:11,940 --> 00:04:13,920 So this holds true for all objects. 81 00:04:13,920 --> 00:04:15,440 Now the thing to remember is this, 82 00:04:15,440 --> 00:04:19,580 strings are objects, everything inherits from objects. 83 00:04:19,580 --> 00:04:24,030 So double equals only works if the variable is referring to the same object. 84 00:04:24,030 --> 00:04:28,020 So you might have seen some double equals seemingly work for strings. 85 00:04:28,020 --> 00:04:29,070 Let's explore that just a bit. 86 00:04:30,970 --> 00:04:37,695 We'll make a new string, firstString this equals, [INAUDIBLE] my name and 87 00:04:37,695 --> 00:04:42,610 we'll say, String secondString is equal to Craig. 88 00:04:42,610 --> 00:04:47,814 And let's just go ahead and we'll say explore 89 00:04:47,814 --> 00:04:53,150 strings are objects and work like objects. 90 00:04:53,150 --> 00:04:56,590 So therefore, they're two separate objects, so they're not the same. 91 00:04:56,590 --> 00:05:02,275 So we'll say firstString is not equal to secondString. 92 00:05:05,770 --> 00:05:07,060 Let's go ahead and run that. 93 00:05:10,070 --> 00:05:11,750 And we get a what. 94 00:05:11,750 --> 00:05:13,805 Huh, how could those two be equal? 95 00:05:13,805 --> 00:05:15,890 Aren't they two completely different objects? 96 00:05:15,890 --> 00:05:17,230 What is the deal? 97 00:05:17,230 --> 00:05:20,310 I thought I understood how this works, and now I'm not so sure. 98 00:05:20,310 --> 00:05:20,830 Ok, so 99 00:05:20,830 --> 00:05:25,400 the good news here is you're not going crazy, those are actually the same object. 100 00:05:25,400 --> 00:05:27,860 So here's the thing, when you create a string like that, you know, 101 00:05:27,860 --> 00:05:29,630 putting it in double quotes? 102 00:05:29,630 --> 00:05:32,460 We're creating what is known as a string literal. 103 00:05:32,460 --> 00:05:35,390 Now since strings are immutable which means, if you remember, 104 00:05:35,390 --> 00:05:40,060 they can't be changed, the compiler does some tricks to optimize. 105 00:05:40,060 --> 00:05:43,700 Since it knows the string won't change it just creates a single instance of that 106 00:05:43,700 --> 00:05:47,980 string and makes all variables refer to that single instance. 107 00:05:47,980 --> 00:05:51,020 It keeps these special references in a special place in memory called 108 00:05:51,020 --> 00:05:52,640 the string pool. 109 00:05:52,640 --> 00:05:55,770 So it's essentially like we saw in the previous object equality, right? 110 00:05:55,770 --> 00:05:56,960 They're pointing to the same thing. 111 00:05:56,960 --> 00:05:59,080 So let's fix our exploration here. 112 00:05:59,080 --> 00:06:05,547 String literals are actually referring 113 00:06:05,547 --> 00:06:11,190 to the same object, all right. 114 00:06:11,190 --> 00:06:13,440 So at compile time that becomes the same object. 115 00:06:13,440 --> 00:06:15,480 So we're gonna put double equals there. 116 00:06:15,480 --> 00:06:16,160 Okay. 117 00:06:16,160 --> 00:06:18,860 And let's add a new one that uses a dynamic string, 118 00:06:18,860 --> 00:06:20,690 one that isn't there at compile time. 119 00:06:20,690 --> 00:06:24,420 So you can kind of imagine this as input coming in from the user. 120 00:06:24,420 --> 00:06:27,130 Now a handy way to make sure that we're creating a unique string is 121 00:06:27,130 --> 00:06:30,240 by using its constructor that actually takes a string. 122 00:06:30,240 --> 00:06:31,420 So let's take a look at that. 123 00:06:32,970 --> 00:06:41,318 So let's say, string differentString is equal to a new String. 124 00:06:41,318 --> 00:06:45,170 They have the same, what seems like to be the same value, so let's do this. 125 00:06:45,170 --> 00:06:51,122 All right, this exploration string objects 126 00:06:51,122 --> 00:06:55,978 that contain the same characters but 127 00:06:55,978 --> 00:07:03,200 point to different objects cannot use double equals. 128 00:07:03,200 --> 00:07:04,370 So let's prove that really quick. 129 00:07:05,820 --> 00:07:09,750 FirstString does not equal a differentString. 130 00:07:13,560 --> 00:07:15,450 Okay, so let's check those assumptions. 131 00:07:18,790 --> 00:07:20,910 Awesome, those are both YAY. 132 00:07:20,910 --> 00:07:25,890 So, one final trick that you might see used is a process called string interning. 133 00:07:25,890 --> 00:07:30,350 You can actually take a user imputed string and add it to the same string pool, 134 00:07:30,350 --> 00:07:33,730 and you do that by using a method on stings called intern. 135 00:07:33,730 --> 00:07:35,200 So let's explore that, just for a quick second. 136 00:07:36,230 --> 00:07:40,499 So let's add a string called anotherString. 137 00:07:40,499 --> 00:07:45,700 And we use that same constructor method, okay. 138 00:07:47,080 --> 00:07:51,960 And let's make a new assumption and we'll say string interning 139 00:07:53,240 --> 00:07:59,040 adds to the same String Pool where literals live, 140 00:08:00,190 --> 00:08:04,880 so you get back the same reference, if it exists. 141 00:08:06,460 --> 00:08:11,148 Okay, so we can say anotherString and 142 00:08:11,148 --> 00:08:18,193 if we do .intern is equal, now we can use double equals. 143 00:08:18,193 --> 00:08:22,669 Let's go ahead and make sure that that works. 144 00:08:22,669 --> 00:08:25,070 Awesome. 145 00:08:25,070 --> 00:08:28,111 So because you almost always are checking object equality and 146 00:08:28,111 --> 00:08:31,036 not concerning yourself with object reference equality, 147 00:08:31,036 --> 00:08:34,559 this is why you almost always should use the equals method, like this. 148 00:08:34,559 --> 00:08:40,681 [BLANK_AUDIO] 149 00:08:40,681 --> 00:08:43,775 And this is true of all objects, so 150 00:08:43,775 --> 00:08:48,280 all objects should use equals to check equality. 151 00:08:48,280 --> 00:08:55,610 So we'll say firstString equals differentString. 152 00:08:55,610 --> 00:09:00,010 And you remember different string was the one that was created with the new. 153 00:09:01,578 --> 00:09:04,150 So see differentString was created with the new string, Craig, and 154 00:09:04,150 --> 00:09:06,210 the first string was a literal. 155 00:09:06,210 --> 00:09:09,310 So they're two separate, they're in, they're in different memory pools. 156 00:09:09,310 --> 00:09:10,360 Let's just make sure that worked. 157 00:09:12,580 --> 00:09:14,000 YAY. 158 00:09:14,000 --> 00:09:16,130 So how does that equals method work? 159 00:09:16,130 --> 00:09:16,910 Well for strings, 160 00:09:16,910 --> 00:09:21,460 it must check that every single character is the same in the other string. 161 00:09:21,460 --> 00:09:24,830 So the way this works is that string has overridden the equals method 162 00:09:24,830 --> 00:09:25,900 on this class definition. 163 00:09:25,900 --> 00:09:29,020 Now I have added a link in the teacher's notes about how you might want to go about 164 00:09:29,020 --> 00:09:31,992 writing your own equals method in your own classes. 165 00:09:31,992 --> 00:09:36,030 All right, let's review the output of your exploration here together one more time. 166 00:09:36,030 --> 00:09:38,440 So primitives use double equals. 167 00:09:38,440 --> 00:09:42,440 Object references use double equals to check if they refer to the same object in 168 00:09:42,440 --> 00:09:46,410 memory, seemingly equal objects are not equal. 169 00:09:46,410 --> 00:09:49,810 Object references must refer to the same object to use double equals. 170 00:09:49,810 --> 00:09:52,300 So that's the only time you should use double equals. 171 00:09:52,300 --> 00:09:56,440 Now string literals are actually referring to the same object. 172 00:09:56,440 --> 00:09:58,700 Remember they go into the string pool together. 173 00:09:58,700 --> 00:10:01,050 String objects that contain the same characters but 174 00:10:01,050 --> 00:10:04,340 point to different objects can not use double equals. 175 00:10:04,340 --> 00:10:08,100 String interning adds to the same string pool where literals live. 176 00:10:08,100 --> 00:10:11,520 So you can get back the same reference, if it exists of course. 177 00:10:11,520 --> 00:10:15,500 And, all objects should use equals to check for equality, and 178 00:10:15,500 --> 00:10:16,670 you can write your own. 179 00:10:16,670 --> 00:10:18,680 So I hope this knowledge will arm you, 180 00:10:18,680 --> 00:10:21,650 as you come up against confusing encounters with strings. 181 00:10:21,650 --> 00:10:25,580 And help remind you that you are, in fact, not going crazy. 182 00:10:27,220 --> 00:10:28,610 So there you go. 183 00:10:28,610 --> 00:10:30,120 I hope that cleared things up for you and 184 00:10:30,120 --> 00:10:33,180 if nothing else it should give you something to refer back to 185 00:10:33,180 --> 00:10:36,190 if you do in fact end up thinking you're losing your mind about strings. 186 00:10:37,430 --> 00:10:38,570 If you like this format and 187 00:10:38,570 --> 00:10:40,990 would like to see more like this please speak up in the forum. 188 00:10:40,990 --> 00:10:43,900 And we'll tackle some more of the more nuance problems that 189 00:10:43,900 --> 00:10:46,300 all we developers encounter from time to time. 190 00:10:46,300 --> 00:10:48,480 As always, your suggestions are very welcome and 191 00:10:48,480 --> 00:10:51,190 really help to shape what we're building together here. 192 00:10:51,190 --> 00:10:52,600 Thanks for hanging out, and see you soon.