 All right, time to start today's mini lecture. And before we get into strings, I wanna cover one other kind of loop here. Let me share my screen and let's go back to one of the programs that we had yesterday. Specifically, this loop here on lines 27 through 36. This is what's called, in fact, I'm gonna put this into the comments here, an N and a half loop. It goes through a certain number of times, but you'll notice there's this input that we do before we enter the loop and again at the end. So we're doing the input twice and this is our one half. Now the disadvantage of it is there's duplicate code. The advantage of it is the first prompt that I give does not have to be the same as the prompt that I give for all of the other times that we go through the loop. So that's the good news. The bad news is I have an input before and an input inside the loop. There's another kind of loop that we can use when we're doing input. When we always wanna get at least one input from the user and that's called the do while loop. Let's save this as age do while dot Java and change the name here. That, by the way, is covered here in the extra exercises book so you can read about it here. You remember that when you have the, do your reading for the chapters, you should always look in the extra exercise book to make sure that you cover anything that's in there as well. Now, when you have a while loop and a for loop, the test for whether we should continue or not is at the top of the loop. And here it's also at the top of the loop. So those are pre-test loops. Do while is a post-test loop, which means that, and I'll put this in the notes here, we have do loop body as long as some condition is true. The body of the loop is always done at least once. And then we check to see if we should continue or not. We're guaranteed at least one trip through the loop body as opposed to while some condition is true in an ordinary while loop if the condition is immediately false, we never do the loop body at all. So that's the big difference between them. This is a pre-test. We do the test before we do the loop body and this is a post-test loop. We do the test after the loop body. So here's what we're gonna do. We're going to set our years here outside of the loop and I'll show you in a moment why. And then what we're going to say, let's do the following. We'll say years becomes get age. And we give it that and enter an age or zero to quit. And we're going to do that as long as years is not equal to zero. So now we have to change our test here. If the years is less than zero, we say the age is not negative. Now we also have to test to see if the years is greater than zero, then it's okay to do this. Otherwise, do nothing, the loop is complete. And whenever I have a do nothing, I can get rid of it. So the years is gonna either be less than zero in which case it's an error, greater than zero in which case we can do our calculations. And if it's not less than or greater than zero, it must be equal to zero and we're going to hit this condition, zero not equal zero is false and we'll drop out of the loop. And I need to get rid of this comment here because it is no longer an n and a half times loop. And now we run it if I say 47, 38 and zero. Well, let's do a negative two here. And it works like a champ. And I probably should do another system.out.print line here by the way because I noticed I didn't have one in my output and that was bugging me. Now, very important, the do while is very different from an ordinary while loop. If I had done this and if I had said int years becomes get age, now if I try to compile it, it will give me an error. And the reason is because remember when you declare a variable inside of braces, its lifetime is only to the closing brace. So as soon as we hit this closing brace, this variable no longer exists and that means I can't test it as part of my condition. That's why I had to put int years outside the loop so that it is available to test in the condition. The technical word for this is the scope of a variable. And I may as well put that in the notes also. The scope of a variable is, let's just call it lifetime. The scope begins at the point the variable is declared and it is accessible until the closing brace of its block, exception. Parameters are available throughout the methods lifetime. So when we have here on this one here, input and prompt have a lifetime of these braces here. It's as if these parameters were declared inside the braces. These are what are called local variables. So here, input is local to main. Years is local to main. If I had created a new variable here, so result here, result perfect is local to get age. And it's scope is from line 18 and it's scope ends at line 20 because that's the end of its enclosing block. So it's important to understand that there is this scope business. And by the way, the fact that there is this thing called local scope is a wonderful thing. The reason it's wonderful is because I can have, for example, public static void method one of int X and I'll do something here. And I can also have another public static void method two with a string called X. And here, in fact, I could have here let's say an integer result, there's no conflict here. This X and result are local to method one. This X is a totally different variable and this result is a totally different variable that belongs to method two. If it weren't for local variables, then we couldn't name our variables without knowing the variable names for every other method. It's as if there's sort of like a wall here. Nobody else can reach into this wall to get this result variable. Nobody can reach inside of this wall to get this result variable. It's only accessible inside the walls. That means I don't have to worry about naming my variables. They're local and they will never conflict with the variables of another method. And again, that's an absolutely wonderful thing because I know I can name my variables, whatever I like, no problem with conflicts. Come back here and let's recompile this because I fixed it now. So that's the do while loop. Speaking of which, it's in the files section on the course. This gives you the difference between the while loop and the do loop, do while loop. The while loop checks first before it does the loop body. The do while does the loop body and then checks afterwards. Okay, next thing to talk about. Let's talk about characters. We've talked a little bit about strings, but I also want to talk about character variables. They're not used a great deal, but they're there and we need to know about them. We can have a character and I'll call it CH. And when you initialize a character, use single quotes because a character can have only one letter in it. So let's use the letter, oh, I don't know. If I want to use printf by the way, I need percent sign C. Characters can be compared directly. Let's say I have another character called otherCH and I'll set it to letter Z. I can ask is CH less than otherCH and the answer is that's true. Now here's an interesting thing that I'm going to do here. Let's say I have a char thirdCH and I'm going to make it a capital Z. And I'm going to ask, okay, is M less than capital Z? And the answer is false. How did that happen? Well, it turns out that a character is essentially the same as an integer. If I wanted, okay, time to put this in the notes, I guess. I remember when you were a kid in grade school and you had a secret code where A was one, B was two, C was three, and you'd write secret messages with this code and you figured that the teacher would never be able to catch on. Of course, they knew about this already, but that's another story. Remember that the computers only deal with numbers. So the question is how do we represent characters, letters in a numeric form and the answer is we use a trick sort of like this, except we use a much more sophisticated version of it called Unicode. And if you go to Unicode.org, you can see that every letter, every letter in every alphabet in fact has a numeric code. So for example, capital A is a 65. Capital B is 66. Lowercase A is 97. Lowercase B is 98. It just so happens. Let's go to Unicode.org. What the heck? It's one of my favorite sites anyway. So, and let's go here to code charts. There we go, presto. And as you can see, this is like just about any alphabet you can imagine, they've got you covered. So for example, oh, let's say we want, oh, Durmuki, okay, there's one with that. Looked at that one lately. And there you can see that these numbers, by the way, are not in base 10, they're in base 16, but these will tell us each character has its own unique number. And it's quite amazing. You can spend a whole ton of time inside Unicode.org. But back to the business at hand, how do we take advantage of it? Turns out if I say, what's the integer version of the letter A, I'm gonna use a cast and it says that's 97, just as I said. Now, remember we were talking about M and Z? M is 109 and capital Z is 90. And that is why lowercase M is actually greater than capital Z, not less. So you've got to be careful with upper and lowercase. One of the things that we can do once we have character variables is we can use the character class and there's a whole bunch of very, very nice methods inside of it. For example, sorry, I just got distracted by one of the methods. I can say character dot is digit. Nope, how about character dot is digit of eight. And that's true. I can ask if something's a letter. Now, one way that we could ask if something is a letter or not is we could do something like this. We could say if character is greater than or equal to A and character is less than or equal to Z or character greater than or equal to capital A and character is less than or equal to capital Z. We need to balance my parentheses there. Should this be a program, probably, but oh well. And what am I missing here? I'm missing a closing parentheses here. There we go. That should work better. And it's a letter because if we look at CH, it's the letter M. Now let's set CH to be something like a dollar sign. And then I go through this same thing again here. And this time it's not a letter. Now, this is all very nice if all we're doing is English. But what if I set character to be the N with the tilde over it, like in Espanol? And now I try this and it says it's not a letter. Well, yes, it is a letter. So we need something better that will take care of unicode letters. And it turns out I can say character.isLetter. If I give it an M, that's true. If I give it a dollar sign, that's false. But it will also work if I give it something like, well, that's hard to read. So let's end unfortunately. Let me help if I were to close my quotes there. So isLetter is very smart. It can handle unicode correctly. So we have things like here, isLetter, isLetter or digit, isLowerCase. Is it a space character? And is it uppercase? And is it whitespace? According to Java, which would be tabs, blanks and new lines. So these are all very, very useful things if we ever need to take a string and find out what is part of, what it consists of. Okay, the only problem we have here is, if I say sorry, see if your goal is blah. It's gonna say, sorry, we can't convert a string to a character. We wanna be able to manipulate strings of characters. And for that we're going to need this string class and that works fine. Now, very important to note here, characters that char data type are primitives like int, double and boolean strings, which is the capital S string data type are objects. And by convention, the names of object data types always begin with a capital letter. I just realized there's something I forgot to cover with loops, but I'll come back to it later. So let's continue with strings. Let's say I have a string that has the word artichokes in it. We can think of this as a collection of individual characters and they are numbered. This is character number zero, one, two, three, four, five, six, seven, eight and nine. So there's a ton of letter word. Let's go back to the J shell here and let's have a string. I'm gonna use S because this is a generic. It doesn't have any great meaning. If I wanna get an individual character, I can say S dot char at. This is get me the character at an index. So if I say get me the character at index zero, it gives me the A. Give me the character at location eight. That's gonna be the E S dot char at nine is letter S. If I need to know how many letters are in a string, I use the length method and that returns me the number of characters in the string. Very important that because this is an object, we use the dot notation to get to its methods. We say S dot char at. This says use the char at method on this string. Use the length method on this string S. So it's a little bit backwards from the way we've been doing normal methods. So be aware that we use dot notation for strings. Well, if this is the case that the length is 10, what happens if I say char at 10? And the answer is kaboom. The index 10 is out of bounds for length 10. Remember, there are 10 characters, but they're numbered zero through nine. We always start counting at zero when we index into a string. Why do we do that? So string indexes always begin at zero and this applies to a lot of other collections of data that we will see in Java. Why? Well, first of all, because history, has historically done that way. And two, if you ever need to write a formula, that uses the index number, the formula has always come out clean if you start counting at zero, but really get messy if your first indexes are one. Note that there are languages that start indexing at one instead of zero, but Java isn't one of them. I'm not even gonna go into ones that do start indexing at one. But that's the main reason that we started at zero because all of our formulas based on an index will come out really clean and really nice. Okay, let's do something here. Let's go back to our template here and save this as show characters, not Java. This is going to be asked user to enter a string and then show its characters one per line. So here we're going to have a string, I don't know, let's call it equals input dot next line. So that will read in the whole line. And then what we're gonna do is we're gonna use a for loop. For index starts at zero as long as the index is less than the length of the string. And we're gonna increase the index one by one. That's what plus plus does. We'll put index and then string dot char at index. And that will be our loop. We're gonna print out the index number, whatever character it is, and then a new line, all that. Well, that was exciting. I forgot to put a prompt there. I mean, nice to have a prompt. So let's put a prompt there. So if I say, for example, playground, turn it again, notice that the blank is a character. Yeah, it's not something that you can ignore. So there are 12 characters in here, number zero through 11. Punctuation marks count as characters. Spaces count as characters. Everything inside of a double-coded string counts. Now, let's rewrite this program or expand it a little bit. So that will ask, let's instead of saying ask user, repeatedly ask user to enter the string and then show its characters one per line. Now the question is, how do we know when to stop? Well, one way we could have them enter the word stop, but why don't we have this say, keep asking until the user enters nothing on the line and presses only the enter key. So we're gonna say, type some text or press only enter to quit. And we're gonna put this inside of a do while loop because we wanna do it at least once. And that also means we're going to have to have our string here declared outside. If we wanna initialize it, we can initialize it to the empty string. This is a string that has a length of zero. Now we're gonna read it in. And then if the length of the string is greater than zero, we'll print everything out. And we'll do that as long as the length of the string is greater than zero. The moment it hits zero, we are finished. And by the way, after this, we're going to do a just for a little bit of extra extra spacing. And let's compile that. Oh my goodness. Well, I've got a whole bunch of interesting things going on here. Ah, what have I done? I forgot my opening brace. There, that's much better. And so if I say blah, and then when I press enter to quit, the program ends. Now you may be wondering why I didn't say something like this. Why don't we do this while string is not equal to the empty string? The answer is while we can compare characters with less than and greater than and equal, equal and not equal, we can't do it with strings because strings are not primitives, they are objects. We have to do something special to compare strings. I'm gonna show you why this is the case. Open up our template file and save this as string equal quality.java. Um, yeah, that's good enough here. So we're gonna ask the user for two strings and then tell if they are the same or not. So here I'm gonna have strings string one is going to be, yeah, and I forgot to put a prompt there. We're gonna say enter the other string and read it in. And then we're gonna say if string one is equal to string two, then we're going to say system dot print line of they are equal. And let's compile that and run it. So if I have dog and cat, they're not equal. If I have cat and catalog, they're not equal. What if I say cat and cat and the answer is they're not equal? Whoa, what the hell happened there? The answer is strings are objects. When I say string one becomes input dot next line, effectively what's happening, I don't know if I'm getting too deep in the weeds on this, but infer penny, infer pound. Let's go here. So I'm gonna have to draw this on the fly here. Let's fill one and where am I? No, no, no, that's a really bad idea. Not what I want at all. Our fill colors, what's happening here is I have string one. And unlike your normal variables where the value is being stored right in there, for example, if I had had something, let me go back up and redo a memory diagram here real quick. If I say something like int n becomes 42, the memory diagram for that, the value 42 is directly stored in memory where n is located. Whereas here, when I did something like string one becomes, the memory area is sitting out here somewhere where I have the word cat. And let me see if I can do this here. Where am I? String one is a reference and it refers to the area of memory where I have the word cat. When I do the same thing with string two, it creates a brand new string out here with a separate area of memory. That means when I now wanna go in here and I say, okay, is string one equal to string two? It's gonna say, all right, let's compare this reference with that reference. Well, these are two different references. They're pointing to two different areas of memory so they are not the same. We need to say, no, no, no, I don't want you to compare where they're referring to. I need you to compare the things that they refer to. I want you to compare this word cat with that word cat, not this reference to memory with that other reference to memory. Cause that's not useful at all. The way I have to do this is I have to use the dot equals method. Now what it's gonna say is, okay, take string one and look at the thing that it refers to and see if that equals the thing that string two refers to. Instead of comparing the references, it compares the things that they refer to which is the actual strings. And now if I say, well, cat and dog are clearly not equal. If I now say cat and cat, cool, they're equal. Remember that I said when I was here in JShell, I was able to do comparisons. I was able to compare M with Z. I cannot compare cat with dog. That's not gonna work because less than will not work on objects, it works on primitives. Well, what am I gonna do? The answer is I'm going to use another method in the string class. And what it's going to do is it's gonna allow me to do comparisons. What I can say is cat dot compare to dog. If it returns a negative number, that means that cat is before dog alphabetically. If it returns zero, they're equal. If it returns a positive number, that means that the first one is bigger than the other one. This requires a program. I'm not sure if I'm going off of the rails here. I may be going a little bit further than the book does on this, but oh well, there you have it. And let's save this as string comparison dot Java. Now I've got to change this and tell how they are related to one another. So here I'm going to have an integer called comparison and it's gonna be string one dot compare to string two. If the comparison is less than zero, then I'll say otherwise, if the comparison is greater than zero, I'll use greater than and then there's no other choice. If there's not less than or equal to zero, less than zero or greater than zero, it must be equal. So if my first string is cat and dog, cat comes out as less than dog, essentially it would come in the alphabet before the other one. If I say let's say zebra versus giraffe, zebra is greater than giraffe, what about cat catalog and cat? The answer catalog is a longer string, so it happens to come out to be a bigger string. And then if we try ibex versus ibex, the two strings are the same. Now this is interesting. I want to see if any of this is even in the book. If it isn't, I'm going to feel awfully silly here. Oh, string comparison, yes, they do talk about it. Okay, thank goodness, I was worried about that. Okay, so we've talked about string iteration. I went way the heck off topic and skipped ahead to string comparison, but that's cool. And so what we're going to do tomorrow is we're going to talk about index of and substrings. But before I go, there is something that I can do right now. And that's, let's do an example program that will repeatedly ask the user to enter a string until they enter the empty string. We know how to do that. And then for each string that they enter, we're going to create a new one that contains only the letters from the original string. So we're going to have a string call, let's call it one line. And we'll set it to the empty string and we're going to have a do while loop, indentation correct. Then we're going to have one line becomes input dot next line. And then if it is not the case that one line dot equals the empty string, we'll process it and we'll do this as long as it is not the case that one line dot equals the empty string. I could have used string length, but now that I have the equals method, I can compare one line to the empty string and see if they are the same. Just as a placeholder. We'll just have to give the line back to us so that we know that it's working. Well, that's exciting. Well, today's my forget the parentheses day clearly or put them in the wrong place day. So if I say XYZ, look at me, XYZ. Okay, perfect, that part's working. Again, read and try and write the whole program and then find out that it doesn't work. I'm testing the input part and now I'm happy with the input part. Any further errors I'm going to be introducing now. So now what we need to do is we need to go through this input string one letter at a time. And if we have a letter, we're going to add it on to the end of our new string. So we're going to have a result string, which is going to be the empty string. And then we're going to set an index to zero, index less than one line dot length, index plus plus. And then we're going to have a character and that's going to be one line dot char at index. If character dot is a letter of CH, then we'll say result string becomes result string plus that character. And it will automatically get converted from a character to a string. So that should work like a champ. And then we'll print out our result string. Let's compile that and see how many errors I've introduced. Oh, none. Well, that's good. And we'll run this. So now if I say ABCDEF, the letters only are ABCDEF, GHI. And because we're using is letter, I can say things like that. That's not what I wanted to say about. There we go. And we can have letters that aren't part of the English alphabet. So there's a quick bonus program that uses the char at creates a brand new string. And then make sure that only letters get into the result and prints that out when we're done. Okay. Tomorrow substrings and index of, we're going to need those because those are incredibly useful. And I may talk about a couple of other string methods that are incredibly useful to know about. Let me check to see if there's anything about strings in this other one. Nope, nothing in there. Okay. I am happy. See y'all tomorrow.