The Complete, Absolute, Definitively Total, and Totally Definitive Java Tutorial; Chapters 4-6

Discussion in 'Resources' started by Maurdekye, Mar 12, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    Maurdekye

    This is a continuation of the previous installment of this tutorial, "The Complete, Absolute, Totally Definitive and Definitively Total Java Tutorial; Chapters 1-3". If you haven't looked there yet, please do, as the following chapters assume you have gone through and read all the information contained within previous chapters. Now, back to the fun stuff!

    - - Chapter Four: ' If ' Statements and Operators- -

    In programming, steps are cool and all, but what if you don't want your program to take a certain step? What if there's something you want to happen instead, depending on the size of a variable? or the value of it, or something else? 'If' statements are what you need. They're used to direct traffic in a program and filter out what doesn't need to be done. Creating an 'if' statement is very simple; you just need the word 'if', a set of parentheses, and a set of opening and closing brackets, preferably spread across multiple lines, like so;

    Code:java
    1. if (true) {
    2.  
    3. }


    What you'll notice is that inside the parentheses I've put 'true'; a value for the datatype boolean. This is the 'condition' of the statement. Hopefully now you'll see how important booleans are; they define the very essence of the 'if' statement, and are intertwined with programming logic.
    The way 'if' statements work is very simple - if the condition is 'true', the code runs. if it's 'false', then everything inside the brackets is ignored. Now obviously, you're not going to just put 'true' or 'false' in them straight: that defeats the purpose of the 'if' statement! What you're going to put in them is 'conditional statements'.
    Code:java
    1. if (varone < var2 && !var4) {
    2.  
    3. }

    What is a conditional statement? It's a combination of datatypes and special symbols, known as 'relational operators', that resolve to either 'true' or 'false'. You can think of them like plus and minus signs, but instead of creating a number, they combine and give, or 'return', a boolean value. For example, the symbol you see above that looks like a left-facing arrow, '<', is called the 'Less Than' relational operator. It takes two numbers on either side and, as you might expect, returns a boolean value. In the case of the Less Than operator, if the number on the left has a lower value than the number on the right, then it returns the value true. If not, it returns false. Simple as that. You can probably guess what '>' on your keyboard stands for. If it's not too obvious, here's a hint - it means 'Greater Than'. It's exactly the opposite of the Less Than symbol, and i'm sure you can figure out how it works. One quirk to these symbols is that if the two numbers are equal, the operator will return 'false'. There's a separate operator for differentiating between whether or not the numbers can be equal and produce a true value.
    Below are all the relational operators you can use between two numbers;
    Code:
    < - Less Than
    > - Greater Than
    <= - Less Than or Equal To
    >= - Greater Than or Equal to
    == - Equal To
    != - Not Equal To
    You can see Less Than and Greater Than in there, but there are a bunch more that you haven't seen yet. Less Than or Equal To works very simply - it's the same as Less Than, but in the case that the two numbers being compared are equal, it returns true instead of false. Works the same way around for Greater Than or Equal To.
    Then there's Equal To, and guess what that means? I'll give you some time to think it over.
    If you're daft enough not to have guessed by now, it means that it only returns true if the two numbers it's comparing are exactly equal to each other. Pretty simple comparison.
    And then there's Not Equal To. Probably the most difficult to understand (at least in comparison), it returns true for any two numbers, except for when they're equal. Like the exact opposite of Equal To. For example, '5 != 32' would return true, '600 != -55' would return true, and as well '7153 != 4239' would also return true. The only statements that would return false would be have to resemble '22 != 22', '46 != 46', or '91827 != 91827'.

    Now that that's out of the way, let's move on to 'conditional operators', like the one you see above, '&&'. Conditional operators are like relational operators, but for booleans only. They compare two true or false values, and return a specific true or false value depending on the type of comparison. The symbol above, '&&', stands for 'And'. It compares two booleans, and returns true only if they're both true. Here is a small table of what different combinations return;
    Code:
      Condition    |  Result
    true  && true  |  true
    true  && false |  false
    false && true  |  false
    false && false |  false
    For example, 'if (true && true) {System.out.println("Line run!")}' would run the print statement within, because the condition resolved the statement to be true; both booleans on either side of the && were true. If just one of them weren't, it wouldn't run.
    There's one more conditional operator besides And; that being '||', which stands for 'Or'.
    Code:
      Condition    |  Result
    true  || true  |  true
    true  || false |  true
    false || true  |  true
    false || false |  false
    'Or' returns true if either the first or the second or both values are true; the only time it returns false is when both values are also false. For example, the line 'if (true || false) {System.out.println("Hello; yes, this is code.")}' would execute the print statement as well, because although one of the values is still false, at least one of them is true, and that's enough for the Or operator to return true.

    And now we get to the final operator type, Unary operators. You can see an example of one above; you didn't seriously think that exclamation mark was a part of the variable's name, did you? It's actually a type of unary operator; negation. Unary operators, unlike other operators, only process a single value, instead of comparing two different ones. The negations operator is very simple, and only works on booleans - it flips them around. You can think of it like putting the word 'not' in front of it. For example, '!true' is like 'not true', and '!false' is almost like 'not false'. In this way, '!true' is equal to 'false', in the same way as '!false' is equal to 'true'. It seems small and dumb, and in some ways, kind of unnecessary, but in programming all things individually seem small and unnecessary. They only become complicated when you make them as such.
    Some other unary operators are listed below, along with what they do;
    Code:
    - - '-', negates numbers; makes positive numbers negative, and negative numbers positive.
    + - Means nothing, exists for internal logical and aesthetic purposes only.
    -- - '--', decrement, short for 'var = var - 1'; permanently removes 1 from a variable.
    ++ - increment, opposite of decrement; permanently adds 1 to a variable.
    ! - negates booleans; flips a boolean value over: true becomes false, and false becomes true.
    
    These operators are the keys to manipulating the conditional phrases of 'if' statements.

    With this newfound knowledge under your belt, you should be ready for a bit of experimentation; go ahead and mix-and-match some booleans with their conditional operators. You might find the more you add, the more complicated it gets; but don't worry! This kind of logic takes some getting used to, so you might as well experiment now while it's fresh in your mind. And don't forget Unary and Relational operators too.

    Now that we've covered 'if', it's time to learn one more word integral to the operation of 'if' statements; 'else'.
    Else can't be used on it's own; it has to be paired with a complementary 'if' in order to function. You generally set up an else statement just below the end of an if statement, like so;
    Code:java
    1. if (true) {
    2.  
    3. } else {
    4.  
    5. }


    You might notice that the else statement is missing the parentheses that the if statement has, and in turn, lacks a condition. This is because the else statement's condition is intertwined with its partnered 'if'; its containing code is only run if the above if statement's condition returns false, not true. Take this code below, for example;

    Code:java
    1. if (360 < 288) {
    2. System.out.println("Code Executed!");
    3. } else {
    4. System.out.println("Code not executed.");
    5. }


    In this case, you would expect the if statement to be ignored, and you'd be correct; but the else statement below would be run, simply because the if statement above didn't. If we modified the condition above slightly, as below;

    Code:java
    1. if (234 < 345) {
    2. System.out.println("Code was run!");
    3. } else {
    4. System.out.println("Did not run.");
    5. }


    The top statement would run also as you'd expect, and the bottom one wouldn't; because whether or not it does depends entirely on the success of the above statement. This functionality is immensely useful and easy to read (as well as being easier on the processor), as opposed to writing a secondary if statement with the opposite condition. If you can't tell now, you will see; it will prove it's usefulness in time.

    Do also note that the print statements are indented farther to the right than the above code; this is proper indentation. From now on, if you ever insert code into an if statement (or other block of code surrounded by curly brackets), always make sure to keep it indented as far deep as it is. It's good practice, as it helps readability tons.

    But we're still not done yet; 'else' has yet one more use; 'else if'. I'll give an example below;
    Code:java
    1. if (x == 5) {
    2.  
    3. } else if (x == 6) {
    4.  
    5. } else if (x == 7) {
    6.  
    7. } else if (x > 7) {
    8.  
    9. }


    As you can see, 'else if' behaves similarly to an 'else' statement in that you have to string it to the end of a normal' if' statement. But it's also similar to an 'if' statement, in that it has a condition. What's going on here?

    Well, when Java sees a string of else if statements attached to an if statement, it will run down the line, skipping all the conditions that return false, until it reaches the end of the string, or a condition that returns true. If it finds a true condition, it runs that code and leaves the string, ignoring any further else if statements in the line, even if their conditions would have also returned true; highest takes priority, in this case.
    But how is this different from just stacking a load of normal if statements together? Well, see the example below;

    Code:java
    1. if (level >= 3) {
    2. System.out.println("You are level 3!");
    3. }
    4. if (level >= 2) {
    5. System.out.println("You are level 2!");
    6. }
    7. if (level >= 1) {
    8. System.out.println("You are level 1!");
    9. }
    10.  
    11.  
    12.  
    13.  
    14. if (level >= 3) {
    15. System.out.println("You are level 3!");
    16. } else if (level >= 2) {
    17. System.out.println("You are level 2!");
    18. } else if (level >= 1) {
    19. System.out.println("You are level 1!");
    20. }


    Let's assume 'level' is equal to one. Running through both blocks of code, we'd see that they would print exactly the same thing to the console;
    Code:
    You are level 1!
    But increasing our level to 2 or more, we'd start to see the difference. The top code block would run the second statement, because 2 is greater than or equal to 2, but it's also greater than or equal to 1, so that if statement would be run as well. The result would look like this;
    Code:
    You are level 2!
    You are level 1!
    But we don't want it to print two messages, only one! Fortunately, running it through the bottom code block, we get something different;
    Code:
    You are level 2!
    It only printed out the single message, because it only ran the code in the single statement. Java started from the top, compared 2 to 3 and determined that the condition was false, so it skipped the first one. It then checked the second condition, and it returned true! So the code ran. But because it's an 'else if' statement and not a normal 'if' statement, Java now knows to skip past all the other malarkey that would otherwise return true, but didn't have the chance, because the string of statements terminated at the second check. This is again, very useful for checking against multiple possible states, and will in the future become very obvious as to why.

    Our final concept isn't really a programming concept, as much as a simple logical leap. If statements have their 'blocks', AKA the stuff inside the brackets, that contains code that is run when they return true, right? And if statements themselves are just more code; so why couldn't you put one if statement inside another? And guess what; you can! This is called, 'nesting';

    Code:java
    1. if (x > 6) {
    2. if (x == 8) {
    3. System.out.println("X is equal to 8!");
    4. } else {
    5. System.out.println("X is greater than 6, but not 8.");
    6. }
    7. } else {
    8. System.out.println("X is not greater than 6.");
    9. }


    In the logic above, one 'if' block is nested inside another; the logic will test the second statement, as long as the first one returns true, and if that statement is true as well, it should run too. You can nest if statements as much and as many times as you like, but be aware that it might get confusing after a while. Also keep in mind that nesting doesn't just work with if statements; it works with other constructs as well, something you'll see in the following chapter.

    And that's all you need to know for if statements, the first part in a two-pair system of constructs, called 'control-flow'. If statements allowed you to skip or run code arbitrarily depending on certain conditions present at the time, but that's only half the puzzle. The other half would be loops.

    - - Chapter Five: Loops and Arrays - -

    Repetition, repetition, repetition. Doing something over, and over, and over again is more important to computers than you might realize. Take this console output for example;

    Code:
    I can count to ten!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    How might you achieve this? Well, knowing what you do currently, you could simply put some print statements in;

    Code:java
    1. System.out.println("I can count to ten!");
    2. System.out.println(1);
    3. System.out.println(2);
    4. System.out.println(3);
    5. System.out.println(4);
    6. System.out.println(5);
    7. System.out.println(6);
    8. System.out.println(7);
    9. System.out.println(8);
    10. System.out.println(9);
    11. System.out.println(10);


    But that's tedious and boring to write out. And what about more numbers? What if you wanted to count to 100? That could take forever!
    Not with loops. Consider the following;

    Code:java
    1. System.out.println("I can count to ten!");
    2. int i = 1;
    3. while (i <= 10) {
    4. System.out.println(i);
    5. i++;
    6. }


    What you see before you is a 'while' loop. Looks kind of like an if statement, doesn't it? That's because it is; sort of. Try running it, and see what happens.

    That's right, it prints out the exact same thing as above, but without all those messy print statements! That doesn't make sense; don't we need those print statements in order to print that many numbers? And you know what, you're right; we do. But the difference here is, we don't need to type them anymore; that's the power of the 'while' loop. Let me explain.

    A while loop is set up similarly to an if statement; it has a condition, and a code block. In fact, it works almost the same right off the bat; when Java reaches a while loop, it checks the condition, and skips it if the condition fails. If the condition validates, then it runs through the code like an if statement. However, when it gets to the bottom of the code block, instead of leaving the loop and continuing to the rest of the code, it goes back to the start and checks the condition again, repeating the process. Each time it does this, it loops back and starts a new 'iteration', or repetition of the code. This logic is crucial to the operation of while loops. Knowing this, let's revisit the code above.

    First, we print 'I can count to ten!' to start the program off. Then, we define a variable, 'i', short for 'iteration'; it will be our marker for which iteration the loop is currently on. This is where we enter the loop.
    It checks the condition, and compares 1 <= 10. This is obviously true, so it runs the code in the loop, which first is printing the value of 'i'; 1. After that, it increments i by 1 (remember the ++ unary operator?) so it becomes 2, and goes back to the top to check the condition again. Again, 2 <= 10, so it runs through and prints i again, which is now 2. Increments by one, i is now 3. Compare, print, increment. Compare, print, increment. And so on; you can see where this is going. Eventually though, i is incremented from 10 to 11. The loop then returns to the top to compare 11 <= 10, and finds that, not only is 11 not less than 10, but it's not equal, either! So it 'breaks' the loop, and we don't print i for an eleventh time. This is how while loops work.

    One thing you should always avoid if possible while making while loops, called 'while true' loops, or infinite loops. You create them by giving a straight 'true' value as the conditional, or otherwise adding a condition that could never possibly resolve falsely, as such;

    Code:java
    1. while (true) {
    2. System.out.println("Another fine mess we've gotten ourselves into.");
    3. }


    When handled incorrectly like above, they will freeze your program, and sometimes even crash your computer, simply because they will go on forever without stopping anywhere. This is called hanging, and it is a problem programmers often face with poorly designed code. The only way to correctly handle an infinite loop is to add a new word somewhere inside it; 'break'.

    Code:java
    1. int i = 0;
    2. while(true) {
    3. i++;
    4. System.out.println(i + " has no good values.");
    5. if (i > 10) {
    6. break;
    7. }
    8. }


    Breaks only works inside loops. When Java reaches one, it immediately jumps right out of the loop, and continues doing everything following it; it does not run any of the remaining lines within the loop, does not pass go, nor does it collect $200. Breaks are completely necessary within infinite loops in order to prevent them from being infinite, but also useful for premature termination of finite types of loops. They're also great for adding extra termination conditions for your loop, if you don't feel like fitting them all / can't fit them all inside the parentheses at the top. In the example above, the infinite loop will run seemingly forever, incrementing 'i' each time. But the 'if' statement acts as a secondary condition for the loop, and will break the loop manually if 'i' reaches a certain limit, ie. greater than 10. At that point the program will terminate, and the last number printed will be 11.
    Another useful keyword for use specifically within loops is 'continue'. Not unlike 'break', when Java sees 'continue', it will skip the remainder of the code in the current iteration. But unlike 'break', instead of leaving the loop, 'continue' will force Java back up to the top, where it will check the condition again to see if the loop should be run. Here's an example;

    Code:java
    1. int i = 0;
    2. while (i <= 4) {
    3. i++;
    4. System.out.println("First message!");
    5. if (i > 2) {
    6. continue;
    7. }
    8. System.out.println("Second message!");
    9. }


    In this loop, the variable 'i' increments once each time, and runs 4 times; the first iteration at 1, the second at 2, third at 3, and fourth at 4. The first two iterations, where i equals 1 and 2, the if statement would not trigger, and both lines would be printed. The output for the first two iterations would look like this;

    Code:
    First message!
    Second message!
    First message!
    Second message!
    But during the third and fourth iterations, 'i' fulfills the condition (i > 2), so the 'continue' statement runs. The full result of all four iterations looks like the following;

    Code:
    First message!
    Second message!
    First message!
    Second message!
    First message!
    First message!
    You can see that the second message was printed only twice, but the first message was printed all four times. This is because during the final two iterations, 3 and 4, the 'continue' is called. This skips over the second print statement, and it isn't printed to the console. However, it still goes back and does the loop over again, which is why the loop runs through the fourth iteration, even though it ran through a 'continue' in the third iteration.

    Breaks and continues are all good and fun, but they don't quite handle what we've been dealing in up until now with loops all that well; counting. Counting in computer programming is so, so very important that there's even a separate type of loop dedicated to doing it more easily than 'while'; that would be a 'for' loop.

    Code:java
    1. for (int i=0;i<22;i++) {
    2. System.out.println("I don't need to define i, it's right here: " + i);
    3. }


    A 'for' loop is a specialized type of loop dedicated to counting, and not much else. The stuffs in it's parentheses may look complicated now, but once you know what each part means it will all become clear.

    A 'for' loop consists of three parts in it's parentheses, all separated by semicolons; the definition, the condition, and the increment, all in that order. Let's compare the above loop to a similar 'while' loop with the same functionality;

    Code:java
    1. int i=0;
    2. while (i<22) {
    3. System.out.println("I do need to define i, because I'm not built for it: " + i);
    4. i++;
    5. }


    Since both loops act the same, they should theoretically have the same contents as each other; just in different places. To compare, let's look at the first part of the 'for' loop, the definition.
    Code:java
    1. int i=0;

    Look familiar? It's exactly the same as the first line in our counting while loop! No surprise there; the variable is defined within the 'for' loop's definition, so we don't need to worry about making one ourselves like in the 'while' loop. It's already there for the taking.

    Next, let's look at the second item in the list, the condition;
    Code:java
    1. i<22;

    Again, very familiar; in fact, it's exactly the same as the conditional statement within the for loop's parentheses! Starting to see a pattern here? The 'for' loop, like the 'while' loop, will check itself against this condition each time it loops back to the top.

    Now finally, the third item in the 'for' loop's construct, the increment;
    Code:java
    1. i++;

    And the same as ever, the exact line appears within the 'while' loop as well. This final line is run at the end of the for loop, right before it goes back to the top.

    Not so complicated anymore, now is it? All in all, a 'for' loop is simply a controlled 'while' loop, meant specifically for counting. It's uses know no bounds, as we can demonstrate here;

    Code:java
    1. System.out.println("I can count to ten!");
    2. for (int i=1;i<=10;i++) {
    3. System.out.println(i);
    4. }


    We've just recreated our original counting program using a 'for' loop instead of a 'while' loop, and it's suddenly much more compact, and in turn, easier to understand. All the information for the loop is in one place; we don't even need more than one line inside the loop itself.

    As you can see, the for loop has it's advantages in counting. But that's not the only thing a for loop is good for; it's time to talk about Arrays.

    --- More to Come! ---
     
Thread Status:
Not open for further replies.

Share This Page