Stargrasper's Java Basics Tutorial SeriesSuppose I should accomplish something...like wave my hands and say it's all magic.
Lesson 0.4: Strings and ConditionalsStrings are groupings of text characters. Internally, they are implmented as character arrays. Arrays are magic. Don't worry about what it is. The String class is an object. More on classes and objects later. The important thing is that Java generally pretends Strings are primitives. For now, virtually everything about Strings is magic.
When defining a String, you enclose the contents in double quotes.
String myString = "This is a String";
The word
String is capitalized because it is an object.
myString is, again, the name of the variable. Stylistically, I prefer and suggest naming variables with more than one word by capitalizing the first letter of every word but the first. Variables should always start with a lower case letter unless they are constants. More on constants later. A single
= in Java signifies an assignment. Anything in double quotes is what you're placing in the string.
It's also worth noting that because String isn't a primitive and Java is pretending it is, Java is doing a lot of stuff for you to make sure you can pretend String is a primitive. We'll discuss what it's doing later. For now, it's magic.
Strings contain text. This includes escape characters. Here's a couple quick examples:
String newLine = "\n";
String tab = "\t";
String quote = "\"";
There are a lot of escape characters. Those are just a few I use a lot.
Now, conditionals. This is kind of a big section. I'll include code excerpts describing functionality and then the whole of the example code at the end.
This is your standard
if .. then .. else block of code, but a bit condenced. For instance, you don't write the word
then.
if ( condition ) {
// execute if condition is true
} else {
// execute if condition is false
}
The
condition above is always a boolean value. Nothing else is allowed in it...with a catch. Here's a quick example:
But first note that there's a little setup...
// Lets just declare and define a couple booleans
boolean condition = false;
boolean condition2 = true;
// Just to make things more clear in the console
String firstExample = "First Example";
// Output to console
System.out.println(firstExample);
// Check whether our boolean condition is true
if ( condition == true ) {
// If it is, execute this code.
// Note that I defined an anonymous String
// and immediately sent it to println
System.out.println("\tCondition Passes");
} else {
// If condition is false, execute this code
// As above, I defined an anonymous String
// and sent it directly to println
System.out.println("\tCondition Fails");
}
/*
* Note that a conditional will only ever execute either
* the true code or the false code. It will skip
* whichever block of code is not needed for the
* conditional
*/
You can do the opposite, too. That is, check if the condition is false.
System.out.println("\nSecond Example");
/*
* Now this gets a bit more confusing.
* The conditional passes as true if
* the condition being checked is true.
*
* If condition is false, the whole
* expression passes as true.
*/
if ( condition == false ) {
System.out.println("\tCondition Passes");
} else {
System.out.println("\tCondition Fails");
}
Just because a conditional is checking if a condition is true, that doesn't mean that the specific thing you're checking is true. As above, my if statement can pass as
true if I'm checking
condition == false and condition is
false. Don't forget you can do this. It's bad style to always check if something is true and then not have any code to execute when it is.
System.out.println("\nThird Example");
/*
* People get confused and think that they should
* always be checking if something is true
* even if they only want to execute code
* when a condition is false. The above
* code demonstrates that this isn't necessary.
*
* In fact, stylistically, you should never have
* an if block be empty like this.
*/
if ( condition == true ) {
// noop
} else {
System.out.println("\tCondition Fails");
}
Slight note,
noop is an Assembly command meaning "no operation". Because comments are ignored, Java thinks there is nothing at all written there. It's a placehold to keep us from getting too confused as looks like this to Java:
System.out.println("\nThird Example");
if ( condition == true )
else
System.out.println("\tCondition Fails");
It's bad style to do that. Instead, you should reverse the logic that the conditional is checking and just leave off the else clause entirely.
System.out.println("\nFourth Example");
/*
* It is entirely legal and encouraged to
* leave off the else statement if you
* don't want to execute code there
*/
if ( condition == false ) {
System.out.println("\tCondition Passes");
}
Okay, great. There are a lot of situtations where I want to check a sequence of things. Is it a bird? No? Fine, is a plane? No? Fine, is it Superman? Yeah! You'll do this by hooking conditionals together. I call this "cascading ifs".
System.out.println("\nFifth Example");
/*
* Further more, you can cascade if statements
* together to form chains that I will henceforth
* be referring to as cascading ifs
*/
if ( condition == true ) {
System.out.println("\tCondition Passes #1");
} else if ( condition2 == true ) {
System.out.println("\tCondition Passes #2");
} else {
System.out.println("\tCondition Fails Entire Cascade");
}
Cascading ifs are a nice alternative to things like switch, which is more magic I'll get to later. Basically, the code tries to execute the next block of code after the else. That happens to be another if statement. Again, it is skipped entirely if the first conditional passes.
Programmers are lazy bums. We don't want to type anything more than we really have to. "If I can understand what it's supposed to do, why can't the computer". Hence, we created a method of not having to explicitly ask whether a boolean is true or false. If you input the boolean name on it's own, Java is assuming you want to know if it is true.
System.out.println("\nSixth Example");
/*
* You don't have to ask it whether the boolean
* is true explicitly. Java will implicitly
* ask that if all you do is enter the boolean
*/
if ( condition ) {
System.out.println("\tCondition Passes");
} else {
System.out.println("\tCondition Fails");
}
But I'm a lazy bum who doesn't want to type more than I have to! What if I want to check if that boolean is false? Well, use the NOT operator.
System.out.println("\nSeventh Example");
/*
* You can use the same notation to check
* if a boolean is false.
*
* In Java, ! is the NOT operator
*
* The following code reads as
* "if not condition"
* or
* "if condition is false"
*/
if ( !condition ) {
System.out.println("\tCondition Passes");
} else {
System.out.println("\tCondition Fails");
}
The NOT operator reverses whatever logic it is attached to, so...
!true == false;
!false == true;
if ( a != b ) {
// They don't match
}
Up to this point, I've lied to you. I told you that conditional statements only take boolean values. Here's the catch I mentioned earlier...you can put logical expressions into them. As long as it resolves to a boolean, it doesn't matter what it is. In fact, checking
if ( condition == true ) isn't a boolean at all! It's an expression that resolves to a boolean. Same with
if ( condition == false ), it's an expression that evaluates
condition. The only time we actually entered a straight boolean value into our conditional was when we used
condition without asking what it was. That is,
if ( condition ) is actually checking a boolean.
if ( !condition ) is checking a boolean.
if ( true ) and
if (false) are checking booleans. Virtually everything else is evaluating an expression.
System.out.println("\nEighth Example");
/*
* You don't actually have to enter a boolean into
* the conditonal. You can enter an expression that
* resolves to a boolean. We did this earlier when
* asking for 'condition == false'. It is an
* expression that resolves to true if it passes.
*
* No real reason we need to limit ourselves to
* booleans, though. The expression can be
* anything that resolves to a boolean.
*/
byte a = 2;
byte b = 3;
byte c = 5;
// if a + b is c
if ( a + b == c ) {
System.out.println("\t" + a + " + " + b + " = " + c);
} else {
System.out.println("\t" + a + " + " + b + " =/= " + c);
}
/*
* You'll note that I can link different things together
* in a string by using the + operator. It's shorthand
* for String.append(string). In other words, magic.
*/
We should take a short time to talk about brackets and scoping. Brackets signify a block of code. Between a matching set of brackets is its own little universe. At the end, anything created inside that block ceases to exist. This is called scoping. Code within a block is said to exist in that scope. For example...
/*
* Stargrasper
* Updated 1/8/2012
*/
package com.bay12forums.stargrasper.javatutorial.lesson3;
public class Scoping {
public static void main(String[] args) {
System.out.println("Start");
// Initialize something
String everywhere = "This can be seen from anywhere in the main()";
/*
* I can open a code block pretty much
* anywhere I want.
*/
{
System.out.println("\tFirst Block");
/*
* From here to the closing bracket is a semi-isolated
* universe. We can see anything in the outer brackets,
* so we can see the String everywhere.
*
* Now we declare and define num.
*/
int num = 5;
System.out.println("\t\tnum = " + num);
}
/*
* See that closing brace right above this comment?
* At that point, num stopped existing.
*/
System.out.println("\n\tBetween Blocks\n");
{
System.out.println("\tSecond Block");
/*
* Normally, we can't have two variable of
* the same name. But I can name another
* variable num because we are outside
* the scope of the first block and thus
* the num from that block no longer
* exists.
*/
int num = 10;
System.out.println("\t\tnum = " + num);
}
}
}
Okay, how often are you really going to create independant blocks of code like in that example? I've legitimately done it exactly twice. More reasonably, you'll do this...
if ( condition ) {
int num = 5;
}
// Some time later...
if ( condition2 ) {
int num = 3;
}
This works because num stopped existing after the first if block ended.
When Java executes a condition, it runs the next "line" of code. If you use brackets, Java pretends the block is a "line" for purposes of what to run with respect to the conditional.
System.out.println("\nNinth Example");
/*
* When you execute an if-else, Java executes the next
* "line" of code. Brackets make Java think the enclosed
* block is a line. That means that so long as you
* only need to execute one block of code, this
* is perfectly legal syntax.
*
* Stylistically, please don't do this. It's great
* until you modify the code wanting to add to
* that if statement, forget to add the brackets,
* and then spend a week trying to figure out
* why it isn't working.
*/
if ( condition )
System.out.println("\tConditon Passes");
else
System.out.println("\tCondition Fails");
While this does work, I stylistically say you shouldn't ever do it. The reason is maintanance. If you change that code, you might break the conditional and get caught trying to figure out why it won't work because you forgot to add brackets so you could run more than one line. It's a style thing. I think the brackets make it easier to read, anyway.
There are times when I want to check more than one condition. I can use cascading ifs if I want to check them each for failure in order, but if I just want to check several things as once, it'd be nice to do it with one conditional. Here's how we do it.
System.out.println("\nTenth Example");
/*
* You can check multiple conditions in a
* a couple of different ways.
*/
if ( condition ) {
if ( condition2 ) {
System.out.println("\tConditions Both Pass");
} else {
System.out.println("\tCondition1 Passes and Condition2 Fails");
}
} else {
System.out.println("\tCondition1 Fails or Both Conditions Fail");
}
/*
* This is messy. Why should I use two if statements
* when I can use one and just check them both?
*
* To check two statements, use the AND operator.
* Java used && as its AND operator
*/
if ( condition && condition2 ) {
System.out.println("\tConditions Both Pass");
} else {
System.out.println("\tConditions Fail; one, the other or both");
}
/*
* Alternatively, I might want to check if either
* one of the is true. For that we use the
* OR operator.
*
* The OR operator is ||
*/
if ( condition || condition2 ) {
System.out.println("\tConditions Pass, one, the other, or both");
} else {
System.out.println("\tConditions Fail, both of them");
}
/*
* I can use any boolean operator here.
*/
Here are the boolean operators
1. | = bitwise OR - TRUE iff either or both of two booleans are TRUE.
2. & = bitwise AND - TRUE iff both of two booleans are TRUE.
3. ^ = XOR - TRUE iff both of two booleans are different, ie, either is true and the other false, FALSE if both are TRUE or both are FALSE. Ludicrously useful.
4. ! = NOT - TRUE iff given boolean is FALSE, ususually used to reverse logic of a boolean.
5. || = OR - TRUE iff either or both of two conditions are TRUE.
6. && = AND - TRUE iff both of two conditions are TRUE.
7. == = EQUALS - TRUE iff both of two values are the same.
8. != = NOT EQUALS - TRUE iff both of two values are not the same.
9. ?: = IF-THEN-ELSE - If IF is true, replaces statement with THEN, otherwise replaces statement with ELSE.
* iff - Mathematical shorthand for "If And Only If"
That last boolean operator? It's actually shorthand for the conditional statement. Here's the syntax:
condition ? outputIfTrue : outputIfFalse
That whole block doesn't quite work like a normal conditional. In a normal conditional, Java executes code based on whether the condition is true or false. In this, Java replaces that whole statement with either the code for
outputIfTrue or
outputIfFalse based on whether the condition is true, using the first for true and the second for false. Here's a quick example:
System.out.println("\nEleventh Example");
/*
* There is an entirely different, shorthand
* way to handle conditionals. It is
* traditionally know as ?: notation.
*
* This is an inline notation that I can plug
* directly into println.
*/
System.out.println(condition ? "\tPass" : "\tFail");
Because I promised, here's the code for the conditionals I've been excerpting from.
/*
* Stargrasper
* Updated 1/8/2012
*/
package com.bay12forums.stargrasper.javatutorial.lesson3;
public class Conditional {
public static void main(String[] args) {
// Lets just declare and define a couple booleans
boolean condition = false;
boolean condition2 = true;
// Just to make things more clear in the console
String firstExample = "First Example";
// Output to console
System.out.println(firstExample);
// Check whether our boolean condition is true
if ( condition == true ) {
// If it is, execute this code.
// Note that I defined an anonymous String
// and immediately sent it to println
System.out.println("\tCondition Passes");
} else {
// If condition is false, execute this code
// As above, I defined an anonymous String
// and sent it directly to println
System.out.println("\tCondition Fails");
}
/*
* Note that a conditional will only ever execute either
* the true code or the false code. It will skip
* whichever block of code is not needed for the
* conditional
*/
// More example
System.out.println("\nSecond Example");
/*
* Now this gets a bit more confusing.
* The conditional passes as true if
* the condition being checked is true.
*
* If condition is false, the whole
* expression passes as true.
*/
if ( condition == false ) {
System.out.println("\tCondition Passes");
} else {
System.out.println("\tCondition Fails");
}
System.out.println("\nThird Example");
/*
* People get confused and think that they should
* always be checking if something is true
* even if they only want to execute code
* when a condition is false. The above
* code demonstrates that this isn't necessary.
*
* In fact, stylistically, you should never have
* an if block be empty like this.
*/
if ( condition == true ) {
// noop
} else {
System.out.println("\tCondition Fails");
}
System.out.println("\nFourth Example");
/*
* It is entirely legal and encouraged to
* leave off the else statement if you
* don't want to execute code there
*/
if ( condition == false ) {
System.out.println("\tCondition Passes");
}
System.out.println("\nFifth Example");
/*
* Further more, you can cascade if statements
* together to form chains that I will henceforth
* be referring to as cascading ifs
*/
if ( condition == true ) {
System.out.println("\tCondition Passes #1");
} else if ( condition2 == true ) {
System.out.println("\tCondition Passes #2");
} else {
System.out.println("\tCondition Fails Entire Cascade");
}
System.out.println("\nSixth Example");
/*
* You don't have to ask it whether the boolean
* is true explicitly. Java will implicitly
* ask that if all you do is enter the boolean
*/
if ( condition ) {
System.out.println("\tCondition Passes");
} else {
System.out.println("\tCondition Fails");
}
System.out.println("\nSeventh Example");
/*
* You can use the same notation to check
* if a boolean is false.
*
* In Java, ! is the NOT operator
*
* The following code reads as
* "if not condition"
* or
* "if condition is false"
*/
if ( !condition ) {
System.out.println("\tCondition Passes");
} else {
System.out.println("\tCondition Fails");
}
System.out.println("\nEighth Example");
/*
* You don't actually have to enter a boolean into
* the conditonal. You can enter an expression that
* resolves to a boolean. We did this earlier when
* asking for 'condition == false'. It is an
* expression that resolves to true if it passes.
*
* No real reason we need to limit ourselves to
* booleans, though. The expression can be
* anything that resolves to a boolean.
*/
byte a = 2;
byte b = 3;
byte c = 5;
// if a + b is c
if ( a + b == c ) {
System.out.println("\t" + a + " + " + b + " = " + c);
} else {
System.out.println("\t" + a + " + " + b + " =/= " + c);
}
/*
* You'll note that I can link different things together
* in a string by using the + operator. It's shorthand
* for String.append(string). In other words, magic.
*/
System.out.println("\nNinth Example");
/*
* When you execute an if-else, Java executes the next
* "line" of code. Brackets make Java think the enclosed
* block is a line. That means that so long as you
* only need to execute one block of code, this
* is perfectly legal syntax.
*
* Stylistically, please don't do this. It's great
* until you modify the code wanting to add to
* that if statement, forget to add the brackets,
* and then spend a week trying to figure out
* why it isn't working.
*/
if ( condition )
System.out.println("\tConditon Passes");
else
System.out.println("\tCondition Fails");
System.out.println("\nTenth Example");
/*
* You can check multiple conditions in a
* a couple of different ways.
*/
if ( condition ) {
if ( condition2 ) {
System.out.println("\tConditions Both Pass");
} else {
System.out.println("\tCondition1 Passes and Condition2 Fails");
}
} else {
System.out.println("\tCondition1 Fails or Both Conditions Fail");
}
/*
* This is messy. Why should I use two if statements
* when I can use one and just check them both?
*
* To check two statements, use the AND operator.
* Java used && as its AND operator
*/
if ( condition && condition2 ) {
System.out.println("\tConditions Both Pass");
} else {
System.out.println("\tConditions Fail; one, the other or both");
}
/*
* Alternatively, I might want to check if either
* one of the is true. For that we use the
* OR operator.
*
* The OR operator is ||
*/
if ( condition || condition2 ) {
System.out.println("\tConditions Pass, one, the other, or both");
} else {
System.out.println("\tConditions Fail, both of them");
}
/*
* I can use any boolean operator here.
*/
System.out.println("\nEleventh Example");
/*
* There is an entirely different, shorthand
* way to handle conditionals. It is
* traditionally know as ?: notation.
*
* This is an inline notation that I can plug
* directly into println.
*/
System.out.println(condition ? "\tPass" : "\tFail");
}
}
Post EpilogueThere's a huge amount of information here and I'm sure I missed some things. If it's anything important, I'll come back to it. Promise. Conditionals are one of those very, very big topics. Kind of like the next topic (arrays, loops, math stuff I forgot) probably will be as well. As always, please ask questions and please give comments.
I wanted to do some more creative things, but this lesson got really long, really fast. I'll show cool tricks later, I guess. Particularly, I really wanted to talk more about XOR. You can basically use it to replace conditionals if you know what you're doing. I'm also holding off on switch statements for now, but that should come fairly quickly as well. This took far too long to write and got really long, so I'm breaking my habit of having two chapterlets per update.