Chapter 4 - Intermediate Java

Arrays

Arrays are useful data structures that allow you to collect objects into groups and have easy access to them. Java, unlike other languages, treats arrays as actual structures that can be passed or treated separately. Arrays can store any kind of object but they must be of the same type. For instance, you can have an array of characters, an array of integers, but not an array of integers and characters (unless you create an array of arrays).

You create an array much in the same way as creating any of the simpler data structures. After the type declaration add empty brackets to tell the compiler the object will be an array rather than a simple variable. You can declare an empty array by assigning it a name only. To actually create and populate an array you can either use the new operator or explicitly list the array members.

	String[] namesofPeople;
	namesofPeople = new String[15];
	int[] phoneNumbers = new int[100];
	int[] ages = {10, 23, 55, 78};
	String[] colors = {"red", "blue", "green"};

The first line declares an array and assigns it a name but does not actually create it. The second line then creates the 15 element array in line one. The third line declares and creates an array with 100 elements in one line. The new operator creates the array of the size included and fills the array with elements. For numeric arrays it fills it with 0's, for character arrays it fills it with '/0's, for boolean arrays it fills it with false values, and for everything else null values are used. The fourth and fifth lines create arrays and fill them with explicit values. The array created is of the same size as the number of values you provide.

To access the values stored in an array you simply give the name and number that refers to the position in the array. It is important to remember that the first element in the array is accessed with 0 not 1. For example:

	ages[0]				returns the integer 10
	ages[3]				returns the integer 78
	colors[0]			returns the string "red"
	colors[2]			returns the integer "green"
	colors[3]			returns an error
	phoneNumbers[100]		returns an error

Modifying an array is similar to modifying any other data structure:

	ages[0] = 15;			sets the first element in ages to the integer 15
	colors[1] = "black';		sets the second element in colors to the string "black"

If your arrays are created dynamically at runtime you can get the size of your array by using the length operation.

	ages.length			returns the integer 4
	phoneNumbers.length		returns the integer 100

This is important to know so your program does not go beyond the bounds of your array and return an error.


	import java.applet.*;
	import java.awt.Graphics;
	
	public class ArrayDemo extends Applet {
	
		String[] message = {"Hello ", "from ", "an ", "array..."};
		int[] numbers = {1, 2, 3, 4, 5};
		int[]	numbers2 = new int[5];
		int x, y, z;	

			public void init() {
			resize(300, 100);
			x = numbers[1];
			numbers2[4] = 316;
			y = numbers2[4];
			z = numbers2[3];
			
		}
	
		public void paint(Graphics g) {
			g.drawString(message[0], 10, 10);
			g.drawString(message[1], 40, 10);
			g.drawString(message[2], 70, 10);
			g.drawString(message[3], 90, 10);
			int x = numbers[1];
			String answer1 = java.lang.Integer.toString(x);
			String answer2 = java.lang.Integer.toString(y);
			String answer3 = java.lang.Integer.toString(z);
			g.drawString("answer1 = " + answer1, 10, 60);
			g.drawString("answer2 = " + answer2, 10, 75);
			g.drawString("answer3 = " + answer3, 10, 90);
	
		}
	
	}

Figure 4.1

Notice that answer3 is 0 because the new operator fills a numeric array with 0's. It would have been easier to access the message array members with a for loop but that is explained in the next section.

Conditionals

Conditional statements give you more flexibility when writing Java code. It allows you to test certain values or states and then act accordingly depending on the results.

The if conditional allows you to execute a boolean test (true or false). The optional else statement catches any cases that were not true in the previous if statements.

	if (x > y)
		g.drawString("x is greater than y", 10, 10);

The above example tests to see whether the value of x is greater than the value of y. If this test returns true than the string "x is greater than y" is printed on the screen. If the test returns false nothing happens and the program would continue on.

	if (x > y)
		g.drawString("x is greater than y", 10, 10);
	else
		g.drawString("x is not greater than y", 10, 10);

The above example is similar but catches the case if the test returns false. Rather than doing nothing, this code would print the string "x is not greater than y" to the screen.

If you need to execute several commands after the test surround your commands with curly braces to block them off into a group.

	if (x > y && x > z) {
		g.drawString("x is greater than y and z", 10, 10);
		question = true;
		}
	else {
		g.drawString("x is not greater than y and z", 10, 10);
		question = false;
		}

It is possible to nest if statements inside other if statements to continually test a value. For example:

	if (x == 1) 
		g.drawString("x equals 1", 10, 10);
	else if (x == 2) 
		g.drawString("x equals 2", 10, 10);
	else if (x == 3) 
		g.drawString("x equals 3", 10, 10);
	else if (x == 4) 
		g.drawString("x equals 4", 10, 10);
	else
		g.drawString("x is greater than 4 or less than 1", 10, 10);

Java provides the switch statement which is equivalent to the nested if statement in some cases (equality tests on numbers) and may be easier to code. Note the switch statement will not work for strings and some other data types so you must use nested if statements in these cases.

	switch (x) {
		case 1:
			g.drawString("x equals 1", 10, 10);
		break;
		case 2:
			g.drawString("x equals 2", 10, 10);
		break;
		case 3:
			g.drawString("x equals 3", 10, 10);
		break;
		case 4:
			g.drawString("x equals 4", 10, 10);
		break;
		default:
			g.drawString("x is greater than 4 or less than 1", 10, 10);
	}

This statement is equal to the previously shown statement that used nested if's. The switch statement tests x's equality with each value following case and executes the statement if it matches. If none match then the default statement is executed. The break statements tell Java to "break out" of the switch statement. This is necessary because Java will continue to execute commands down the switch statement once a match is found. For instance, if there were no break statements in the above example and x=1 all the strings would be printed (on top of each other).

Java also provides a shorthand version of the if conditional that returns a value.

	test ? result1 : result2;

	z = x > y ? 1 : 0;

The test is evaluated and result1 is returned if it is true otherwise result2 is returned. If x were greater than y, the integer 1 would be assigned to the variable z.

Loops

Loops provide an easy way to repeat a statement or group of statements a certain amount of times without having to explicitly copy the code. It also allows you to repeat statements a number of times that is not determined until runtime which would be impossible by cutting and pasting statements in the actual code.

The for loop initializes itself, tests the condition, increments the index value, and executes the statements.

	for (initialization, condition, index)
		statements;

	int x = 5;
	for (j = 0; j < 3; j++)
		x = x + 1;

In the above example, the loop first initializes the variable j and sets it equal to 0. This part of the loop is executed only the first time. The loop then checks the condition to see whether j is less than 3. If this evaluates to true the statements are executed for that iteration. The index part of the loop then increments the variable j and the loop runs again if the condition is met.

The first iteration of this loop initializes j to 0 and tests it against the value 3. Since 0 is less than 3 the statement "x = x +1" is run which makes x equal to 6. The variable j is then incremented to 1.

In the second iteration, j = 1 which is still less than 3 so x is set to equal 7. The variable j is then incremented to 2.

In the third iteration, j = 2 which is still less than 3 so x is now set to equal 8. The variable j is then incremented to 3.

The fourth iteration fails because 3 is not less than 3. Since the condition now evaluates to false the statement is not run and the loop is done. The result is x = 8 which occurred because this loop executed "x = x + 1" three times.

Any portion of a for loop can be left empty by just including the semicolon.

The while loop repeats its statements while the condition evaluates to true.

	while (condition) {
		statements;
	}

	while (x < 10) {
		y = y + 10;
		z = y;
		x++;
	}

The example uses a while loop but could have easily used a for loop instead. It continuously checks to see if x is less than 10. When the condition evaluates to true it adds 10 to y, sets z equal to y, and then increments x. Notice I need to increment x in the body of the while loop. When the condition evaluates to false the loop stops. If the condition is initially false the while loop will do nothing. If you need the loop to execute at least once you should use the do...while loop instead.

The do...while loop is basically the same as the while loop except that the statements are executed at least once. The while loop checks the condition before it starts where the do...while does not.

	do {
		statements;
	} while (condition);

	do {
		y = y + 10;
		z = y;
		x++;
	} while (x < 10);

These loops are essentially equal but if the condition in both were changed to "x > 10" they would behave differently. The while loop would never execute the statements but the do...while loop would execute its statements once before exiting.

	import java.applet.*;
	import java.awt.Graphics;
	
	public class LoopDemo extends Applet {
	
		int x = 5;
		int y = 5;
		int i, j;
		int k = 11;
		int l = 11;
		int m = 100;
		int n = 100;
	
		public void init() {
			resize(300, 100);
			for (i = 0; i < 3; i++)
				x = x + 1;
			for (j = 0; j < 3; j++)
				y = y * 10;
			while (k < 11 && k > 0) {
				m = m + 100;
				k--;
			}
			do {
				n = n + 100;
				l--;
			} while (l < 11 && l > 0);
			
		}
	
		public void paint(Graphics g) {
			String answer1 = java.lang.Integer.toString(x);
			g.drawString("x is equal to " + answer1, 10, 10);
			String answer2 = java.lang.Integer.toString(y);
			g.drawString("y is equal to " + answer2, 10, 30);
			String answer3 = java.lang.Integer.toString(m);
			g.drawString("m is equal to " + answer3, 10, 50);
			String answer4 = java.lang.Integer.toString(n);
			g.drawString("n is equal to " + answer4, 10, 70);
	
		}
	
	}

This extended loop example shows the use of each type of loop statement in Java. Notice the while loop doesn't do anything to the value of m but the do...while loop increases n by 1100. This is because the while loop never gets executed (initial condition evaluates to false) but because the do...while loop executes its body once before testing the initial condition it does get started.

Figure 4.2

If you need to get out of a loop for some reason use the break statement. When the loop hits a break statement the loop is exited immediately. If you just want to skip a certain iteration of the loop use the continue statement. The continue statement makes the loop stop its current iteration and start the next one.

Both break and continue apply to the current loop but they support an optional label argument that can override this behavior.

	top:
	for (i = 0; i < 10; i++)
		for (j = 10; j < 20; j++) {
			if (j > 20)
				break top;
			x = x + 1;
		}

A label is a word followed by a colon (not a semicolon). In the above example if j is greater than 20 for some reason the program breaks to the top label and starts again.

Conventions

It is a good idea to follow some conventions when you start coding in Java. This will help you keep different objects straight and make it easier to determine their function. It doesn't matter what conventions you follow but you should be consistent.

For example, you could start variable names with lowercase letters and class names with uppercase letters. This would allow you to immediately tell which items were classes and which were variables.

Also, it is a good idea to comment your code for readability. The code that makes perfect sense to you today may not be clear three months from now when you need to make a major revision.