1. Practice
By now, you should be comfortable supplying all of the "green code" for a program. To practice this, save and compile the following program:
public class SampleCode { public static java.util.Scanner scanner = new java.util.Scanner(System.in); public static void main(String[] args) { // this program does nothing! } }First, notice that this program does compile and does run. Of course, it does nothing, but that's what we told it to do! Now for the practice:
- Problem #1: Starting from the sample code above, and without looking at other code, write a program that prints out the number of inches in a yard. Use a nice UI.
- Problem #2: Starting from the sample code above, and without looking at other code, write a program that reads in a number of yards from the user, and prints out that number of yards converted to inches. Use a nice UI.
2. String concatenation
Here we will learn a useful shortcut called string concatenation. Say we have a variable "f" which represents the number of frogs on a log. We may wish to display this information as such (if, say, f equals 10):
There are 10 frogs on the log.
Here is the Java code to do this:
System.out.print("There are ");
System.out.print(f);
System.out.println(" frogs on the log.");
We do this print/print/println pattern so often, it would be nice if there was a shorthand way to do this on one line. Well, there is! We can use the "+" operator to "add" strings together. When we do this, the result is a new string that is just the first string followed by the second string. For example, "abc" + "def" equals "abcdef".This also works for a string and a number, so "abc" + 5 equals "abc5". Java converted the number 5 into the string "5" for us, and then proceeded with adding two strings as above. So? Well, now we can use this to print our frog information with one statement:
System.out.println("There are " + f + " frogs on the log.");See how this works? Java will convert whatever value f is assigned (say, 15) into a string (like "15"), then add that string to "There are " to get "There are 15", and then add that string to " frogs on a log." to get "There are 15 frogs on the log." How convenient!
Now it's your turn.
Problem #3: Solve this problem twice: once using print and println commands to display the data, and then again using string concatenation and only one println to display the data.
A ferry captain has to be sure that the combined weight of all the cars and trucks on the ferry is not too heavy for the ship. To help with this task, write a program that reads in the number of trucks and the number of cars on the ferry, and computes the approximate weight of those vehicles. Assume that cars weigh one ton and trucks weigh 10 tons. Its UI should look exactly like this (where, as always, the underlined values are entered by the user):
Number of trucks: 6
Number of cars: 31
6 trucks and 31 cars weigh about 91 tons.
3. Integer Division
Recall that an integer is a number with no decimal part. So, 3, 4, and 5 are integers, but 3.14 is not an integer. When Java divides one integer by another integer, the result is always an integer. This can be confusing at first, but you will get used to it.
So, 4/2 equals 2, just as you would expect. But what about 5/2? In math, you learned that this equals 2.5 (that is, 2 and one-half). But 5 and 2 are both integers, so the answer must be an integer, too. So we would expect the answer to be either 2 or 3. But which one? You might expect Java to round the answer to the nearest integer, but this is not what it does! Instead, it truncates the answer -- simply ignoring the decimal portion of the answer. So 2.5 becomes 2, and so in Java 5/2 becomes 2. See?
Now for some practice:
Problem #4: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
System.out.println(10/3);
System.out.println(-10/3);
System.out.println(100/50);
System.out.println(99/50);
System.out.println(49/50);
Problem #5: Write a program that reads in the height of two people and prints out their average height. It should work exactly like this:
First person's height in inches: 74
Second person's height in inches: 62
The average height for these two people is 68 inches.
4. The Remainder Operator (%)
So far, we have learned how to add, subtract, multiply, and divide integers. Java also provides a remainder operator (%), where x%y returns the remainder when x is divided by y. For example, when we divide 13 by 5 we get a remainder of 3. So, 13%5 equals 3. Similarly, 15%5 equals 0 and 201%5 equals 1.
Now for some practice:
Problem #6: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
System.out.println(10%3);
System.out.println(-10%3);
System.out.println(100%50);
System.out.println(99%50);
System.out.println(49%50);
System.out.println(0%21035);
System.out.println(1%31063);
Problem #7: Write a program that reads in a time in seconds and prints out the same amount of time in minutes-and-seconds, as such:
Total number of seconds: 124
124 seconds equals 2 minutes and 4 seconds.
Note that your program should use the remainder operator (%) to determine how many seconds are left after the minutes are taken out.
Problem #8 (harder): Write a program that reads in a time in seconds and prints out the same amount of time in hours-minutes-and-seconds, as such:
Total number of seconds: 7384
7384 seconds equals 2 hours and 3 minutes and 4 seconds.
Note that your program should use the remainder operator (%) twice: once to determine how many seconds are left after the hours are taken out, and again to determine how many seconds are left after the minutes are taken out.
So you know: The remainder operator (%) is also called the modulus operator, or for short, just the mod operator. Some programmers even read it this way: so they would read "7%3" as "seven mod three".
5. Overflow
As we have discussed, computers store all information as 1's and 0's. For this reason, integers are usually stored using the binary or base 2 number system (with one small change to make it work better with negative numbers). Also, for the past 20 years or so, most computers have used a "32-bit architecture", which means that integers are usually stored using 32 bits. Java works this way -- it uses 32 bits to store its integers.
So? Well, because of this, Java has a largest integer that it can store! The largest integer is precisely 2,147,483,647, which is just over 2 billion. Using "int" variables, Java cannot store numbers larger than this.
But what happens if your program includes math with an answer that is larger than 2 billion? It turns out that Java simply computes the wrong answer and your program just keeps running. This is known as overflow. Here is an example:
int x = 2000000000; // x equals 2 billion
System.out.println(x); // works fine
int y = x + x; // y should equal 4 billion
System.out.println(y); // OVERFLOW!!!Compile and run this code. See what it does? Two billion works fine, but 4 billion is larger than the largest integer, and so Java cannot store this value. Instead, Java comes up with the value -294,967,296. Never mind the details, the point is: Java added 2 billion plus 2 billion and came up with a negative answer! This is the result of overflow.
We can show that 2,147,483,647 is in fact the largest possible number with this simple program:
int x = 2147483646; // one less than the largest possible 32-bit integer
x = x + 1;
System.out.println(x); // works fine
x = x + 1;
System.out.println(x); // OVERFLOW
When you run this program, you can see that when you add 1 to 2,147,483,646, you get the expected answer of 2,147,483,647. But when you add 1 to 2,147,483,647, you get a negative answer. See?
Problem #9: Just as there is a largest positive integer in Java, there is also a smallest negative integer. A good guess at that value would be -2,147,483,647. This is very close, but not exactly correct. Write a program similar to the one above that shows what the smallest negative number is.
Hint: If you are not at the smallest negative number, then you should be able to subtract one and get a valid result. But if you are at the smallest negative number, when you subtract one you will overflow and get a bogus result.
6. Operator Precedence
What happens when you enter "2+3*4" on most calculators? Well, there are two possibilities. Either the addition comes first, so the calculator would find that 2+3 equals 5, and then 5*4 equals 20, so the answer would be 20. Or the multiplication comes first, so it would first find that 3*4 equals 12, and then 2+12 equals 14, so the answer would be 14. Which is it?
On most calculators, the answer is 14. Java works this way, too. In Java, multiplication is performed before addition.
Now for some practice:
Problem #10: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
System.out.println(3+4*5);
System.out.println(3*4+5);
System.out.println(2+3*4+5);
System.out.println(2+3+4*5);
System.out.println(2*3+4*5);We can use parentheses to force Java to add two numbers before multiplying. Java computes values in parentheses before other values. So, while 2+3*4 equals 14, (2+3)*4 forces Java to add first, so we get 5*4, which is 20.
More practice:
Problem #11: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
System.out.println((3+4)*5);
System.out.println(3+(4*5));
System.out.println((2+3)*(4+5));We say that operators like addition (a+b) and multiplication (a*b) have precedence. Multiplication has higher precedence than addition, so it comes first. In general, Java computes operators with higher precedence before other operators.
There are more operators to consider. Subtraction (a-b) has the same precedence as addition. Division (a/b) has the same precedence as multiplication. Here is some more practice:
Problem #12: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
System.out.println(5+10/5);
System.out.println(8/4-2);
System.out.println(12-6/3-1);
System.out.println(12/6-3/1);
System.out.println(1+2/3);What about the remainder (or modulus, or mod) operator? It has the same precedence as multiplication and division. Let's practice that:
Problem #13: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
System.out.println(5+10%5);
System.out.println(9%4-2);
System.out.println(12-11%3+1);
System.out.println(9%6-3%1);
System.out.println(1+2%3);
7. Operator Associativity
Java uses operator precedence to choose which operator to compute first. What happens when two operators have the same precedence? In the simplest case, what happens when the operators are the same? In this case, for the operators we are considering, Java computes from left-to-right. We call this the operator's associativity. So, most Java operators have left-to-right associativity.
For example: to compute "20/5/3", Java would first divide 20 by 5 to get 4, then divide 4 by 3 to get 1 (remember, this is integer division). So the answer is 1. If Java worked the other way, it would first divide 5 by 3 to get 1 (again, this is integer division), and then divide 20 by 1 to get 20. Of course, we can force Java to do this with parentheses, but otherwise Java will work left-to-right and get 1 for the answer. Let's confirm this as follows:
System.out.println(20/5/3);
System.out.println(20/(5/3));Compile this code and run it. See how it clearly shows that Java has left-to-right association (at least for division)?
Now for some practice:
Problem #14: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
System.out.println(1+2+3*(4+5)%6);
System.out.println(100/4/3/2/1);
System.out.println(100/4%3*2+1);
System.out.println(5-11%4*2);
8. Increment and Decrement Statements
Adding one to a variable (or incrementing it) is such a common operation that Java provides a shortcut for it: you can replace the statement "x = x + 1;" with "x++;". Consider the following:
int x = 1;
System.out.println(x); // prints 1
x = x + 1; // add one to x (increment it)
System.out.println(x); // prints 2
x++; // increment x
System.out.println(x); // prints 3Compile this code and run it. See how it shows that "x++" adds one to x?
Note that you can use "++x;" as well as "x++;". As statements, these have the same effect of adding one to x. Let's verify this:
int x = 1;
System.out.println(x); // prints 1
x = x + 1; // add one to x (increment it)
System.out.println(x); // prints 2
x++; // increment x
System.out.println(x); // prints 3
++x; // also increment x
System.out.println(x); // prints 4
Compile this code and run it. See how it shows that "++x" also adds one to x?Subtracting one from a variable (or decrementing it) is also common, and so "x = x - 1;" can be replaced by either "--x;" or "x--;". Again, let's confirm this:
int x = 4;
System.out.println(x); // prints 4
x = x - 1; // subtract one from x (decrement it)
System.out.println(x); // prints 3
x--; // decrement x
System.out.println(x); // prints 2
--x; // also decrement x
System.out.println(x); // prints 1
Compile this code and run it. See how it shows that "--x" and "x--" both subtract one from x?
Problem #15: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
int x = 4, y = 3;
System.out.println(x + "/" + y + " = " + x/y);
x++;
--y;
System.out.println(x + "/" + y + " = " + x/y);
++x;
y--;
System.out.println(x + "/" + y + " = " + x/y);
Problem #16: When printing out expressions among strings (using string concatenation), it is a good idea to place your expressions in an extra set of parentheses. To demonstrate why this is true, predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
int x = 4, y = 3;
System.out.println(x + "*" + y + " = " + x*y);
System.out.println(x + "+" + y + " = " + x+y); // be careful here!
System.out.println(x + "*" + y + " = " + (x*y));
System.out.println(x + "+" + y + " = " + (x+y)); // be careful here!
Problem #17: As another example of requiring parentheses, one line in the following example will not compile:
int x = 4, y = 3;
System.out.println(x + "+" + y + " = " + x+y);
System.out.println(x + "-" + y + " = " + x-y);
System.out.println(x + "*" + y + " = " + x*y);
System.out.println(x + "/" + y + " = " + x/y);
Which line will not compile and why won't it compile? Also, how can parentheses fix the problem?
9. Increment and Decrement Expressions
Besides being used as statements, the increment (++) and decrement (--) operators can be used within expressions. This is complicated, however, and should generally be avoided. However, it is common enough that you should know how it works so you can understand Java code that uses this technique.
We start with this example:
int x = 4;
int y = ++x;
System.out.println(x + "," + y); // prints 5,5 (and not 4,5)The first line is clear -- it sets x equal to 4. But what does the second line do? It first increments x, to get 5, and then sets y equal to this value. This is not the same as setting y equal to (x + 1). The difference is that here x is actually changed, too. So x and y both equal 5. Compile and run the code to confirm this.
To further stress this point, let's add the line "y = x + 1;", as such:
int x = 4;
int y = ++x;
System.out.println(x + "," + y); // prints 5,5
y = x + 1;
System.out.println(x + "," + y); // prints 5,6
Compile this code and run it. See how it shows that "y = ++x" and "y = x + 1" are not the same? Both set y equal to x plus one, but the first statement also increments x, whereas the second statement has no effect on x.We see that "++x" adds one to value of x and then uses that value. We call this pre-incrementing. The other form of the increment operator is written as "x++". Notice that the "++" is written after the variable x. The "x++" form is called post-incrementing. It still adds one to x, but it uses the old value of x. For example:
int x = 4;
int y = x++; // post-increment!
System.out.println(x + "," + y); // prints 5,4 (not 5,5)Compile this code and run it. See how it shows that "y = x++" still adds one to x (which ends up with 5 and not 4), but it uses the old value of x (4) and not the new value (5), so y equals 4 and not 5? To review, this example contrasts x++ and ++x:
int x,y;
x = 4;
y = ++x; // pre-increment!
System.out.println(x + "," + y); // prints 5,5
x = 4;
y = x++; // post-increment!
System.out.println(x + "," + y); // prints 5,4Compile this code and run it. See how it shows that ++x pre-increments x and x++ post-increments x? See how these differ?
Note that when we use "x++" or "++x" in statements (on lines by themselves), they are the same. They only differ when used in expressions. For example:
int x = 4;
System.out.println(x); // prints 4
x++; // increment statement using x++
System.out.println(x); // prints 5
++x; // increment statement using ++x
System.out.println(x); // prints 6We can use the increment operator in arithmetic expressions, too. For example:
int x = 4;
int y = ++x * 3;
System.out.println(x + "," + y); // prints 5,15Compile this code and run it. Be sure you understand what is happening here. On the second line, the value of x is first incremented, so x equals 5, and then this value (5) is multiplied by 3. So y equals 15 (5*3) and not 12 (4*3).
By contrast, here is the same example, only here we use "x++" instead of "++x":
int x = 4;
int y = x++ * 3;
System.out.println(x + "," + y); // prints 5,12Compile this code and run it. What is happening? On the second line, the value of x is first obtained (4), and then it is incremented, so x equals 5, and but the old value (4) is multiplied by 3. So y equals 12 (4*3) and not 15 (5*3).
Note that "--x" (pre-decrement) and "x--" (post-decrement) work in the same way:
int x, y;
x = 4;
y = --x * 3; // pre-decrement
System.out.println(x + "," + y); // prints 3,9
x = 4;
y = x-- * 3; // post-decrement
System.out.println(x + "," + y); // prints 3,12Compile this code and run it. Be sure you understand why pre-decrementing and post-decrementing produce different results, even though both expressions decrement x by one.
Using the ++ and -- operators as statements is straightforward, and is a common practice. However, using the ++ and -- operators in expressions (like y = ++x * 3) can be confusing! For this reason, you generally should not do it. You can generally avoid this practice and simply add another line to perform the increment or decrement. That is, you can replace:
y = --x * 3;
with:
--x;
y = x * 3;
And you can replace:
y = x-- * 3;
with:
y = x * 3;
--x;
Now there is no confusion! So you should take this approach in your code. However, you still must be able to understand other programmers' code that uses pre/post increment/decrement operators in confusing ways.
Problem #18: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
int w = 5, x = 4, y = 3;
System.out.println(w + "," + x + "," + y);
w = x++ / --y;
System.out.println(w + "," + x + "," + y);
w = ++x * y--;
System.out.println(w + "," + x + "," + y);
++x;
--y;
w++;
System.out.println(w + "," + x + "," + y);
10. Assignment Operators
We just saw how the ++ and -- operators can be used to add or subtract one to a variable, either as a standalone statement or within an expression. What if we want to add or subtract some value besides one? Say, two?
As you may have guessed, Java provides a shortcut for this as well using the += and -= operators. Consider this line:
x = x + 2;
This is exactly the same as:
x += 2;So we see that "+=" can be used to add a value to a variable. Similarly, "-=" can subtract a value. For example:
int x = 4;
System.out.println(x); // prints 4
x += 2;
System.out.println(x); // prints 6
x -= 4;
System.out.println(x); // prints 2Compile this code and run it. See how it shows how += and -= work?
As with ++ and --, you can use the += and -= operators both as statements (which is a good idea) and in expressions (which is not). For example, here we use the += and -= operators in expressions:
int x, y;
x = 4;
y = (x += 2) * 2; // add 2 to x, then use that value
System.out.println(x + "," + y); // prints 6,12
x = 4;
y = (x -= 2) * 2; // subtract 2 from x, then use that value
System.out.println(x + "," + y); // prints 2,4Besides += and -=, Java provides several other assignment operators:
x += 2 is the same as x = x + 2
x -= 2 is the same as x = x - 2
x *= 2 is the same as x = x * 2
x /= 2 is the same as x = x / 2
x %= 2 is the same as x = x % 2Now for some practice:
Problem #19: Predict what the following code will print out. Write down your answers. Then (and only then) run the program and compare its output to your answers.
int w = 5, x = 4, y = 3;
System.out.println(w + "," + x + "," + y);
y *= ++w / --x;
System.out.println(w + "," + x + "," + y);
w /= (y -= 4 * (x %= 2));
System.out.println(w + "," + x + "," + y);
w += x += y += 3;
System.out.println(w + "," + x + "," + y);
w = x = y %= 3;
System.out.println(w + "," + x + "," + y);
11. More Practice
Problem #20: Write a program that reads in some number of cents, and prints out how a cashier would give you that amount of money using only nickels and pennies, as such:
Total number of pennies: 27
27 cents equals 5 nickels and 2 pennies.
Hint #1: you should use as many nickels as possible (so you will never use more than 4 pennies, right?).
Hint #2: you should use a variable named "nickels" that equals the result of dividing the cents by 5.
Hint #3: you should use a variable named "cents" that equals the remainder after you divide the cents by 5. Why?
Putting these hints together, you may want to have a program that looks like this:
int cents, nickels, pennies;
// Add some code here to read in the total number of cents
nickels = cents / 5; // remember this is integer division
pennies = cents % 5; // why?
// Add more code here to print out the answer
Problem #21: Modify the previous program so that it prints out how a cashier would give you that amount of money using dimes as well as nickels, and cents, as such:
Total number of pennies: 27
27 cents equals 2 dimes, 1 nickels and 2 pennies.
Hint #1: You should use as many dimes as possible (so you will never use more than one nickel, right?), and then you should use as many nickels as possible.
Hint #2: we will add another variable, "dimes", which equals cents%10 (why?). This time, though we will set the variable "cents" equal to the remainder after we take out the dimes. This allows us to use the rest of our program from above without changing it. Think carefully about this to be sure you understand why it works. So you would have code like this:
int cents, dimes, nickels, pennies;
// Add some code here to read in the total number of cents
dimes = cents / 10;
cents = cents % 10; // THIS IS THE KEY LINE
// So now "cents" holds the number of cents remaining
// AFTER we have removed all the dimes (right?)
nickels = cents / 5;
pennies = cents % 5;
// Add more code here to print out the answer
Problem #22: As you may have guessed, now we'll include dollars and quarters. Modify the previous program so that it prints out how a cashier would give you that amount of money using dollars, quarters, dimes, nickels, and cents, as such:
Total number of pennies: 594
594 cents equals 5 dollars, 3 quarters, 1 dimes, 1 nickels and 4 pennies.
Hint #1: You should use as many dollars as possible, then as many quarters as possible, and so on.
Hint #2: You will want to set "cents" equal to the remainder each time after you remove all the dollars, then all the quarters, and then all the dimes.