See also:
This page explains Java if-statements and boolean expressions with example code and exercises. See also the associated CodingBat live boolean logic practice problems to practice boolean logic code or study for an exam. Written by Nick Parlante.
if (temperature > 100) { System.out.println("Dang, it's hot!"); }The simplest if-statement has two parts -- a boolean "test" within parentheses ( ) followed by "body" block of statements within curly braces { }. The test can be any expression that evaluates to a boolean value -- true or false. The if-statement evaluates the test and then runs the body code only if the test is true. If the test is false, the body is skipped.
Another common form of if-statement adds an "else" clause such as with the code below which prints one message or the other:
if (temperature > 100) { System.out.println("Too darn hot"); } else { System.out.println("At least it's not more than 100"); }The if/else form is handy for either-or logic, where we want to choose one of two possible actions. The if/else is like a fork in the road. Under the control of the boolean test, one or the other will be taken, but not both. For example, the famous Robert Frost poem is a thinly disguised comment on the importance of the if/else structure:
Two roads diverged in a wood, and I - I took the one less traveled by, And that has made all the difference.
There are four comparison operators:
The similarity of == and .equals() can be confusing, so here is a suggested rule: Every value in Java is either a primitive (e.g. int) or an object (e.g. String). Use ==, <, >=, etc.. with primitives like int. Use .equals() with objects like String and Color. Since the dereference dot (.) only works with objects, you can remember it this way: if it can take a dot then use .equals() (e.g. a String), otherwise use == (e.g. an int).
It is also possible to use == with objects. In that case, what == does is test if two pointers point to exactly the same object. Such as use of == is a little rare in Java code, and so it's simpler to concentrate on using equals() with objects, and == only with primitives.
int i = 6; // ok boolean a = false; // ok boolean b = "hello"; // NO, String and boolean are different boolean c = "false"; // NO, "false" in quotes is a String! String s = "false"; // ok
Suppose we have int variables score and temperature, the code below prints "It's hot out and so am I" if the score is 10 or more and temperature is 100 or more. The && is true only if both of the two booleans it connects are true:
if ( (score >= 10) && (temperature >= 100) ) { System.out.println("It's hot out, and so am I!"); }Suppose we are in a bad mood if our score is less than 5 or the temperature is 32 or below:
if ( (score < 5) || (temperature <= 32) ) { System.out.println("I'm in a bad mood"); }Finally, the "not" operator ! (an exclamation mark) goes to the left of a boolean expression and inverts it, changing true to false and false to true. Suppose we want to print something if it is not the case that the score is less than 5, we could write that as:
if (!(score < 5)) { System.out.println("Score is 5 or more)"); }First, the expression (score < 5) evaluates to true or false, and then the ! inverts the boolean value. The result is that the body runs if the expression (score < 5) is false, which is to say it runs if (score >= 5) is true. (We could equivalently write the if-statement with (score >= 5), but the point was to demonstrate the !).
// Say something mean if not satisfied if (! ((style>=8) && (bribe>=5)) ) { System.out.println("Je n'think so"); }With combinations of !, <, >=, etc. there can be a few different ways to code what amounts to the same thing. As a matter of style, we prefer the code that reads most naturally to express the goal of the code. For example, the following is equivalent to the above, although I find it near impossible to decipher:
// Say something mean if not satisfied if (!(!(style<8) && !(bribe<5))) { ...Here is another equivalent form, which is not so bad...
// Say something mean if not satisfied if ((style<8) || (bribe<5)) {...Java also has "bitwise" operators & and | (more rarely used) which are different from && and ||. If your boolean code will not compile, make sure you did not accidentally type a bitwise operator (&) instead of a boolean operator (&&).
if (! ((style>=8) && (bribe>=5))) {works fine without parentheses around the comparisons, since the comparisons have high precedence than && ||:
if (! (style>=8 && bribe>=5)) {The not ! has a high precedence (as do all the unary operators), so we need parentheses to force the ! to evaluate after the >= and &&. Remember that all the unary operators, such as !, have a high precedence. To evaluate something before the !, we frequently need to put the something in parentheses like this: !(something). For example:
if (! i < 10 ) { ... // NO does not workThe precedence of the ! is too high, it wants to execute before the <. To fix this, we add parentheses around the (i < 10) so it goes first:
if (!(i < 10 )) { ... // Ok
if (i==2 || i==3) { ...If i is 2, the boolean expression evaluates to true after the i==2 is true. It does not even look at the i==3. Suppose we want to do something if 100.0/i is less than 10. We use short-circuiting to screen out the i==0 case, checking it before the division. If i is 0, the expression short-circuits out before the division:
if (i!=0 && (100.0/i < 10.0)) { ...A common use of short-circuiting is to call a method on an object, but only if the pointer to the object is not null. For example, suppose we have a bear pointer which may or may not be null:
if (bear!=null && bear.hasCubs() && bear.isMom()) { ...// run!
if (score > 100) { score = 100; System.out.println("Score is 100"); }However, if there is only one statement in the body (say just "score = 100;") then it can be written without the curly braces:
// One-statement body written without curly braces if (score > 100) score = 100;Or, in fact it can be written all on one line:
// One-statement body written without curly braces if (score > 100) score = 100;
if (score > 100) score = 100; System.out.println("Score is 100"); // BUG, this code compiles fine, but it gives the appearance // that the println() is controlled by the if, which it is not.Unfortunately, without the curly braces, the code can have a deeply misleading appearance. Above, it appears (due to the misleading indentation) that the println() is under the control of the if-statement, but it is not. The "score = 100;" is controlled by the if-statement, and the println() is just the next statement that is outside of the control of the if-statement. To avoid this situation where the code says one thing, but the indentation and spacing suggests something else, we prefer to write out our if-statements and loops with the curly braces for maximum clarity.
if (score >= 100) { ... // version 1 if (100 <= score) { ... // version 2 if (score > 99) { ... // version 3Though the three versions are effectively the same, as a matter of style we prefer the code that reads as the most natural translation of the goal of the code. In this case, the first is probably the best translation of the idea "score is 100 or more".
if (day <= 5) { // 1..5 are weekdays System.out.println("Hi ho, hi ho, it's off to school we go..."); if (day == 1) { // Something extra for Mon System.out.println("It's not the weekend any more!"); } } else { // 6..7, it's the weekend System.out.println("Hit the snooze button now!"); }
if (score >= 300) { System.out.println("Perfect!"); } else if (score >= 200) { System.out.println("Very good"); } else if (score >= 50) { System.out.println("Good job"); } else { System.out.println("Everyone is good at something."); System.out.println("You are good at something else!"); }The if-else chain checks each test, working from top to bottom. The first test that is true runs the corresponding body, and then exits the whole chain. So for the above code, if the score is 250, the program prints "Very good" and exits the chain. The result of the if-else chain is to choose one piece of code from among many. The optional final "else" in the chain does not have an "if" and plays a catch-all role in case all the others are false.
For the design of the bowling code above, notice that the tests must be done in the order shown, working from high to low. Each test relies on the fact that the tests above have been checked already, and were all false. For example, if the chain gets to the (score >= 50) line, we know that (score >= 200) must have been false, and so the score is 199 or less.
// suppose num is an int if (num == 3) { ...That code works fine. Suppose instead that you have a boolean variable "isSummer" and you want an if-statement that runs if isSummer is true. Here is one way to write that code:
if (isSummer == true) { ...That code works ok, but it is a little longer than necessary. It also has a problem if you accidentally type a single "=" instead of "==":
if (isSummer = true) { // BAD bug ...Unfortunately, the above code compiles fine. When run, it assigns true to isSummer, and then the if-statement always passes since the test is always true. This bug is very hard to spot, since the "=" looks reasonable. A shorter way to write the code, and a good defense against the above bug is to use the boolean variable directly without "==" or anything, like this:
if (isSummer) { ...Or for not isSummer, just:
if (!isSummer) { ...Code that uses the boolean variable directly like that is nice and short.
public class Bear { ... // Returns true if the bear is a mother bear public boolean isMother() { ... // Returns true if the bear has cubs with it public boolean hasCubs() { ... }Now suppose we are writing the meetBear() code for a Backpacker, used when the Backpacker meets a bear in the woods:
// Code for when we meet a bear in the woods void meetBear(Bear bear) { System.out.println("Oh look, a bear."); if (bear.isMother()) { System.out.println("Hi mom!"); } if (bear.hasCubs()) { System.out.println("Hi cute little bears!"); } if (bear.isMother() && bear.hasCubs()) { System.out.println("Oh @#$@#$!, Run!"); } }Another way to write the mother if-statement uses "== true" like this:
if (bear.isMother() == true) { System.out.println("Hi mom!"); }That code will work fine, but it is not the best style. The "== true" adds nothing, since the if-statement itself already checks if the test is true. Therefore, it is better to write it the direct way:
if (bear.isMother()) { System.out.println("Hi mom!"); }
public class Car { private int myGasoline; private int myBattery; ... // Returns true if we are low on fuels public boolean isLow() { if ((myGasoline + myBattery) < 10) { return true; } else { return false; } } }The above code will work fine. It has a boolean test checking for low fuels, and depending on that it runs either "return true;" or "return false;". But there is a better way. We can cut out the if-statement middle-man. Notice that the boolean in the if-test (true or false) happens to be the same as the value we want to return. If the test value is true, we return true. If the test value is false, we return false. So you can just return the test value directly! In the short version below, we compute the desired boolean value with the expression "((myGasoline+myBattery) < 10)", and just return that value (which at runtime will either be the value true or the value false, depending on the gasoline and battery levels):
public boolean isLow() { // Compute (true or false) if we are low, // and return that boolean value directly. return ((myGasoline + myBattery) < 10); }Writing the method the long way is not terrible style (i.e. we won't mark off for it!), but it's nice to be comfortable enough with boolean values to write it the short way.
/* * Do we go on a second date with someone? * The given chemistry is in the range 0..100 and isSchool * is true if it is during the school year. The answer is yes if chemistry is * 60 or more, or 40 or more not in the school year. */ public void secondDate(int chemistry, boolean isSchool) { if (chemistry>=60 || (!isSchool && chemistry>=40)) { System.out.println("Sure!"); } else { System.out.println("I don't want to spoil our friendship"); } } /* * Returns true if the person gets into Stanford. * Given gpa = 0...4.0, isGates = child of Bill Gates, * isDarth = associated with Darth Vader. * To get in: must not be associated with Darth Vader at all * Gpa must be over 3.95 * Or gpa over 1.0 if child of Bill Gates */ public boolean getIntoStanford(double gpa, boolean isGates, boolean isVader) { if (!isVader && (gpa>=3.95 || (gpa>=1.0 && isGates))) { return true; } else { return false; } } // Variant, where we return the boolean directly public boolean getIntoStanford2(double gpa, boolean isGates, boolean isVader) { return (!isVader && (gpa>=3.95 || (gpa>=1.0 && isGates))); } // Variant, where we use an if-return for the darth case. // I think maybe this one is the best -- the one big expression is // a bit hard to follow, this version makes it more obvious. public boolean getIntoStanford3(double gpa, boolean isGates, boolean isVader) { if (isVader) { // no way, it'a deal killer! return false; } // Otherwise just use gpa and isGates return (gpa>=3.95 || (gpa>=1.0 && isGates)); }
// For all values of num and bool. what does this print? public void test1(int num, boolean bool) { if (num >= 90 || !bool) { System.out.println("A"); } else { System.out.println("B"); } } // For all values of num and bool, what does this print? // Note: deciphering this is hard, harder than most // code-writing problems, but it's a good way to // exercise your logic skills. I can only figure it // out by making a little chart of the possible values. public void test2(int num, boolean bool) { if (num >= 90 && bool) { System.out.println("Tic"); } else if (num >= 20) { System.out.println("Tac"); } else { System.out.println("Toe"); } }
test1: bool true false num >=90 A A num < 90 B A test2: bool true false num >= 90 Tic Tac 20<=num<90 Tac Tac num < 20 Toe Toe
// suppose we have doubles d1 and d2 // We use the Math.abs() standard method that computes // absolute value // check if d1 and d2 are essentially equal // (if the absolute value of their difference is less // than 1e-6 (i.e. 0.000001) if (Math.abs(d1 - d2) <= 1e-6) {...
CodingBat.com code practice. Copyright 2012 Nick Parlante.