Let's go back to our paycheck example from section 3.1, but let's change the rules a bit. Suppose we decide to reward our employees who work more than 30 hours a week with a little bonus. From now on these employees will get a $100 bonus in addition to their normal paycheck. To incorporate this into our program we need a way to say "if the employee worked more than 30 hours, add $100 to her paycheck." Java provides exactly that with the if statement. Here's how it would work for our example:
if (hours > 30) {
paycheck = paycheck + 100;
}
Here's how our program will look with our new addition:
import java.util.Scanner;
public class Paycheck {
public static void main(String[] args) {
int hoursWorked;
int paycheckAmount;
int payrate;
Scanner input = new Scanner(System.in);
System.out.print("Enter hours worked: ");
hoursWorked = input.nextInt();
System.out.print("Enter rate of pay: ");
payrate = input.nextInt();
paycheckAmount = hoursWorked * payrate;
if (hoursWorked > 30) {
paycheckAmount = paycheckAmount + 100;
}
System.out.println("The amount of the paycheck is "
+ paycheckAmount + " dollars.");
}
}
enter hours worked: 31
enter rate of pay: 10
the amount of the paycheck is 410 dollars.
The general form of the if statement in Java is
if (<condition>){
<statements>
}
If the condition of the if statement is true, then the statements inside the if statement get executed. If the condition of the if statement is false, then the statements inside the if statement do not get executed. In either case, the program continues execution with the statement following the if statement.
Notice that we are very careful with our indentation here. The statements inside an if statement are always indented further than the if statement itself. This is because the statements inside an if statement are part of the if statement. If we do not indent them, then it does not look like they are part of the if statement. It looks like they are independent statements that come after the if statement. When you are about to type a line of code and you are not sure how far it should be indented, ask yourself the question, "Is this statement part of the statement I just typed (for example, a statement inside of an if statement), or does it simply come after the statement I just typed?" If it is part of the statement you just typed, it should be indented further than that statement. If it simply comes after the statement you just typed, it should be indented the same amount as the statement you just typed.
I also need to make some comments about the open and close curly braces. First, if there is only one statement inside the if, then you technically do not need the open and close curly brace. Personally I think that it is safer and clearer to just always use the open/close curly brace, even if there is only one statement. But many programmers (perhaps most) like to leave them off when they can. How you write your own code is up to you. However, you certainly need to understand what happens when the curly braces are left off. You are very likely to see an example like this on an exam. Consider this code:
if (hours > 40)
statement1;
statement2;
statement3;
In this case, both statement2 and statement3 will get executed regardless of the value of "hours", because statement2 is not inside the if. Make sure you understand this, and ask me about it if you do not!
Secondly, I should point out that often you will see a different placement of the open curly brace. Some programmers prefer to place that brace down on the next line after the if, instead of at the end of the line. Again, I think that the placement indicated above is better, but you may choose your favorite and use it. I'm pretty sure that most professionally written Java code will follow the style indicated above.
Now we're ready for our next challenge. After a trial period we have concluded that our $100 bonus policy isn't working that well. We've decided to go with a standard overtime payment plan. In other words, each employee will be paid at one and a half times her normal rate of pay for any hours worked in excess of 40. Here's our first attempt:
import java.util.Scanner;
public class Paycheck {
public static void main(String[] args) {
int hoursWorked;
int paycheckAmount = 0;
int payrate;
Scanner input = new Scanner(System.in);
System.out.print("Enter hours worked: ");
hoursWorked = input.nextInt();
System.out.print("Enter rate of pay: ");
payrate = input.nextInt();
if (hoursWorked <= 40) {
paycheckAmount = hoursWorked * payrate;
}
if (hoursWorked > 40) {
paycheckAmount = (int) (40 * payrate + (hoursWorked-40) * payrate * 1.5);
}
System.out.println("The amount of the paycheck is "
+ paycheckAmount + " dollars.");
}
}
(Technical note: in this example I'm required by Java to initialize paycheckAmount to 0 when I declare it, because Java won't let me declare a variable that it can't confirm will receive a value at some point in the program. You can ignore that "= 0" for now.)
This solution works fine, but it would be nice if we could simplify it a bit. The situation here is that we have 2 alternative statements, and we always want to execute exactly one of them. We never want to execute none of them, and we never want to execute both of them. Java provides a statement especially for this kind of situation, since it happens a lot. It's called the if-else statement and it goes like this:
#include <iostream>
import java.util.Scanner;
public class Paycheck {
public static void main(String[] args) {
int hoursWorked;
int paycheckAmount = 0;
int payrate;
Scanner input = new Scanner(System.in);
System.out.print("Enter hours worked: ");
hoursWorked = input.nextInt();
System.out.print("Enter rate of pay: ");
payrate = input.nextInt();
if (hoursWorked <= 40) {
paycheckAmount = hoursWorked * payrate;
} else {
paycheckAmount = (int) (40 * payrate + (hoursWorked-40) * payrate * 1.5);
}
System.out.println("The amount of the paycheck is "
+ paycheckAmount + " dollars.");
}
}
The general form of the if-else statement is as follows:
if (<condition>){
<statements1>
} else {
<statements2>
}
If the condition is true, then statements1gets executed. If the condition is false, statements2 gets executed. We call statements1 the if-part and statements2 the else-part.
Since the if-else statement in Java is itself a statement, it is possible to have if-else statements inside of if-else statements. When we do this it is called nested statements. For example, let's say that we live in a country where the married people are taxed at lower rates. Here are the tax tables for that country:
| single | married | |
| < $20,000 | 15% | 10% |
| >= $20,000 | 20% | 15% |
Here is a program segment that will compute the tax for a citizen of this country. We'll use the 'm' to indicate the citizen is married and 's' to indicate that they are single.
if (maritalStatus == 's') {
if (income < 20000){
tax = income * 0.15;
} else {
tax = income * 0.20;
}
} else {
if (income < 20000){
tax = income * 0.10;
} else {
tax = income * 0.15;
}
}
Let's follow the execution of this program segment through with a specific example. Let's say that maritalStatus is 'm' and income is $22,000.
Let's try a more complex example. The following program segment will print an "A" if the score is greater than or equal to 90, a "B" if the score is between 80 and 89, a "C" if the score is between 70 and 79, a "D" if the score is between 60 and 69, and an "F" if the score is below 60.
(I see that the text uses the exact same example to illustrate this. The author must have stolen it from me, because I have been using it since long before our text was published :) )
import java.util.Scanner;
public class Grade {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int score;
System.out.print("Enter a score: ");
score = input.nextInt();
if (score >= 90) {
System.out.println("A");
} else {
if (score >= 80) {
System.out.println("B"); // let's call this point X
} else {
if (score >= 70) {
System.out.println("C");
} else {
if (score >= 60) {
System.out.println("D");
} else {
System.out.println("F");
}
}
}
}
}
}
If score is greater than 90 the first if-part is executed and the else-part is skipped. This means that even though the other four conditions are true, only the System.out.println("A"); will be executed, because the other three if-else statements are part of the original else-clause, which is skipped.
Pay close attention to the fact that I did not have to check the upper bound of the range in each condition above -- for example, at the point in the program that I have labeled as "point X", to check for a grade of "B" I didn't have to make sure that score was less than 90, because if score had not been less than 90, execution would never have reached point X. You'll get marked down on your assignments if you use if conditions that are unnecessarily complex because you didn't understand this.
Although this program segment works correctly, it is very difficult to read. In a situation like this, where you have several alternatives and exactly one of them is to be executed, you should structure your nested if-else statements like this:
import java.util.Scanner;
public class Grade {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int score;
System.out.print("Enter a score: ");
score = input.nextInt();
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 70) {
System.out.println("C");
} else if (score >= 60) {
System.out.println("D");
} else {
System.out.println("F");
}
}
}
I think you'll agree that this method is a lot easier to read than the previous example was. When you encounter a complex if-else situation like this, you don't really even have to think too much about all the ifs and elses. Just follow the pattern and realize that exactly one of the alternatives will be executed.
Even though all of our examples so far have had only one statement in each if-clause or else-clause, it is perfectly acceptable to have more than one. For example, if, in our grade example, we wanted not only to print out the grade but to assign the appropriate grade to a character variable called grade, our program segment would look like this:
import java.util.Scanner;
public class Grade {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int score;
char grade;
System.out.print("Enter a score: ");
score = input.nextInt();
if (score >= 90) {
System.out.println("A");
grade = 'A';
} else if (score >= 80) {
System.out.println("B");
grade = 'B';
} else if (score >= 70) {
System.out.println("C");
grade = 'C';
} else if (score >= 60) {
System.out.println("D");
grade = 'D';
} else {
System.out.println("F");
grade = 'F';
}
// program continues....
}
}
We need to talk some more about the <condition> part of the if statement. In our first example (section 3.3), the condition was
hours > 30.
The condition hours > 30 must be either true or false. If hours is greater than 30, then the condition is true. If hours is not greater than 30, then the condition is false. A condition is something that is always either true or false. What I am calling a condition here is more formally known as a boolean expression or logical expression.
Although you will see exceptions to this rule later on, for now you should assume that every condition must involve one of the following six operators (these are relational operators):
| Algebra | English | >Java | Example | Result |
| > | greater than | > | 40 > 30 | true |
| < | less than | < | 40 < 30 | false |
| ≤ | less than or equal to | <= | 40 <= 30 | false |
| ≥ | greater than or equal to | >= | 40 >= 30 | true |
| = | equal to | == | 40 == 30 | false |
| ≠ | not equal to | != | 40 != 30 | true |
Notes about the table above:
One of the most common mistakes that Java beginners make is to use = when they really mean ==. Make sure that you understand the difference.
differences between = and ==
difference #1:
= is the assignment operator.
== is the "is equal to" operator.
difference #2:
When you use =, you are telling the computer to do something. For example,
hours = 30;
means "put the value 30 into the variable hours."
When you use ==, you are asking the computer a question. For example,
hours == 30
means "is the value of hours equal to 30?"
difference #3:
The == is only used in logical expressions. The = is only used in assignment statements.
In assignment statements use =
In logical expressions use ==
In Java we can also use words like "and", "or", and "not" in our logical expressions. They are called logical operators. We use special symbols to represent them. For "and" we use the symbol "&&" (double ampersand), for "or" we use the symbol "||" (double vertical bar), and for "not" we use the symbol "!" (exclamation point). The "|" (vertical bar) is sometimes hard to find on the keyboard. It is the <shift> backslash key, right above the return key.
Example 1:
Problem: Write a logical expression that means "number is between 5 and 15."
Solution:
(number > 5) && (number < 15)
This expression should be read "number is greater than 5 and number is less than 15."
Notice that an expression like 5 < number < 15 won't work in Java. Java would view this as
(5 < number) < 15Since (5 < number) is a boolean value, Java would view this as something like
(false < 15)
Which clearly doesn't make sense.
Example 2:
Problem: Write a logical expression that means "number is not between 5 and 15."
Solution: There are two approaches to this problem. The most obvious approach is to enclose the solution to example 1 in parentheses and then put a "!" in front:
!((number > 5) && (number < 15))
This condition would be read "not [number is greater than 5 and number is less than 15]." In other words, number is not between 5 and 15.
A better solution would be to use "or". In order for number to not be between 5 and 15, it must be either less than 5 or greater than 15!
(number < 5) || (number > 15)
Notice that when you use "and" and "or," you must always have a valid logical expression on both sides of the operator. In other words,
number < 5 || > 15
is not a valid way to express the condition from example 2. The reason it is not valid is that, although there is a logical expression on the left side of the "||", there is not a logical expression on the right side. When you use "not," it must be followed by a condition, as it is in example 2.
It is important to be able to evaluate logical expressions even if they become quite complex. Many bugs are introduced into programs as a result of the programmer's inability to evaluate logical expressions correctly. As you know, when you evaluate a logical expression it always turns out to be either "true" or "false". The way to evaluate an expression that has "and", "or", or "not" in it is to first evaluate each of the more simple expressions, and then apply the following rules:
| Expression | Evaluates to |
| false && false | false |
| false && true | false |
| true && false | false |
| true && true | true |
| false || false | false |
| false || true | true |
| true || false | true |
| true || true | true |
| ! true | false |
| !false | true |
This table of rules can be summarized as follows: When the operator is "and," the expression evaluates to "false" if either one of the operands is "false." When the operator is "or," the expression evaluates to "true" if either one of the operands is "true." "Not" in front of an expression simply reverses its value.
One last thing you need to know about evaluating complex logical expressions before we do a few examples. Between the logical operators, "not" has the highest precedence (is evaluated first), "and" comes next, and "or" is last.
Example 1: Evaluate this logical expression:
| (3 < 7) || !(4 < 8) | |
| true || !true | |
| true || false | (evaluate "not" first) |
| true |
Example 2: Evaluate this logical expression:
| !((3 < 7) || (4 < 8)) | |
| !(true || true) | |
| !(true) | (evaluate inside parentheses first) |
| false |
Example 3: Evaluate this condition:
| (5 < 9) || !(3 < 7) && (4 > 8) | |
| true || !(true) && false | |
| true || false && false | (evaluate "not" first) |
| true || false | (now evaluate "and") |
| true |
Notice in example 3 that if we had evaluated "or" before evaluating "and" we would have gotten an answer of "false" instead of "true."
I have not written this section yet, but it is critical that you read the section in the text on the switch statement.