Spring Semester 2002


Lecture Notes Seventeen: Java arrays. Reading assignment for this is on pp. 431-469 (chapter 11).
Suppose that you want to write a program... I have a feeling of deja vu.

... that reads a set of prices offered by 10 (ten) vendors for a particular product, and then prints them, marking the lowest one. Sounds interesting.

Of course, you need to read in all data items first, before you can start printing them. You can't print them as you read them, can you?

No, your program has to wait until the last of the ten prices has been entered, ... and then print all the items.

Exactly. If I could be sure that there are always ten data items, ...

... then you could store the prices in ten variables: data1, data2, ...data10. Hey, that was my idea!

But such a sequence of variables is not very practical to use. It isn't?

Well, what if you had a hundred data items? Ugh...

Or a thousand? You would have to write quite a bit of code... Or what if the number of vendors is unknown,

... to be specified by the user of your program at run-time. Then what do we do?

Wouldn't it be nice if you could call the entire set of prices by just one name... ... such as price

... denoting the entire sequence? It would, but only if we could easily get to the individual elements of the sequence, like this: price1, price2, ..., pricen,

... where n could be even specified by the user, at run-time (when the program is run). Boy, that would be nice!

That would be a better way of storing such a sequence of data items, wouldn't it? Yes, it would be.

Fortunately Java has a construct that is designed just for such a circumstance. The array construct.

An array is a collection of data items of the same type. Every element of the collection can be accessed separately.

Here's how you define an array of ten floating-point numbers:
double[] price = new double[10];
That was a mouthful. Can we take it apart?

Yes, let's do it in stages. In Java, arrays are objects.

We'll get to that in a second. Essentially we want to define a variable with the name of price.

Exactly, but this variable is of type array of doubles. We use the square brackes ([]) to denote array.

So an array of doubles is declared as
double[]
And to declare a variable price of this type you need to say:
double[] price;

I see you put the type in blue, and the name of the variable in red. Entirely correct.

Now you have a variable (or an array name) but there is no array as of yet. Have we seen this before?

How about Same thing.
Rectangle a;

A variable a is defined, that could store references to a Rectangle object, ... but there's no actual Rectangle as of yet.

I could create one like that: Can you do the same with the an array?
a = new Rectangle(5, 10, 15, 20);

Yes, in the following way: And do we have the array now?
price = new double[10];

Yes, the call new double[10] creates the actual array of 10 numbers. Every element of the collection can be accessed separately.

When an array is first created all values are initialized with 0 ... for an array of numbers such as int[] or double[],

... false for a boolean array, ... or null for an array of objects.

You mean you could create an array of Rectangles too? Of course, how many Rectangles do you anticipate you might later need?

How about also 10?
Then it looks almost the same:
Rectangle boxes = new Rectangle[10];

Very good. All ten slots in array boxes are currently null.

Indeed. To get some values into the array you need to specify which slot in the array you want to use.

That is done with the [] operator. It must follow the name of the array and enclose an integer-valued expression

... called an index or a subscript. Now you need to remember a thing about Strings.

Why Strings? Because it is the same for arrays, and very important here.

What is that? The first element in an array has index 0.

Just like the first character in a String s is accessed with s.charAt(0) (see page 251). So the actual elements in my price array will be identified as: price0, price1, ..., pricen-1 then.

Yes, and n is 10 ... so the subscripts go from 0 to 9.

Also, Java syntax for pricei ... is really price[i],

... where i is an integer-valued expression. In this case, an int variable.

You can't use long, can you? Only if you cast it to int.

int works for me. The index in an array reference has a major restriction.

What is that? Trying to access a slot that does not exist in the array is an error.

So price[10] would be such an error? Yes, it would be, in our case.

Good. Now that we have reviewed all this let's start on the program. Here's how you could find out the lowest price in an array of prices:
double lowest = price[0];
for (int i = 1; i < price.length; i++) 
  if (price[i] < lowest)
    lowest = price[i]; 

What's that: price.length? You've seen something similar with Strings.

Note that there are no parentheses following length and so we can tell about length this: ... it is an instance variable of the array object,

... not a method. Oh, man, this is nifty!

However, you cannot assign a new value to this instance variable. In other words, length is a final public instance variable.

This is quite an anomaly. Normally, Java programmers use a method to inquire about the properties of an object.

You just have to remember to omit the parentheses in this case. Using length is a much better idea than using a number such as 10,

... even if you know that the array has ten elements. Note that i is a legal index for an array a if 0 <= i and i < a.length

Therefore the for loop ... is extremely common for visiting all elements in an array.
for (int i = 0; i < a.length; i++) 
  do something with a[i]

Can we write the program now? Yes, let's do that:
class Price {
    public static void main(String[] args) {
	double[] price = new double[10]; 
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.println("Please specify the ten prices:"); 
	for (int i = 0; i < 10; i++) {
	    System.out.print(i + "> "); 
	    price[i] = c.readDouble(); 
	    // the user presses enter!
	}
	System.out.println("Thank you!"); 
	double lowest = price[0]; 
        for (int i = 0; i < price.length; i++) {
	    if (price[i] < lowest) {
		lowest = price[i]; 
	    } 
	} 
	System.out.println("*** Lowest price computed."); 
	System.out.println("Here are the prices: "); 
	for (int i = 0; i < price.length; i++) {
	    System.out.print("Price " + (i + 1) + ": "); 
            System.out.print(price[i]); 
            if (lowest == price[i]) {
		System.out.println(" *** lowest price");
	    } else {
		System.out.println(); 
	    } 
	}
    } 
} 

This program illustrates the points discussed thus far. I could improve on it, and in many ways.

We'll do that in a few minutes. May I, at least, show you a sample run?

Certainly. Here it is:
frilled.cs.indiana.edu%java Price
Please specify the ten prices:
0> 3
1> 4
2> 5
3> 6
4> 3
5> 4
6> 5
7> 6
8> 3
9> 4
Thank you!
*** Lowest price computed.
Here are the prices: 
Price 1: 3.0 *** lowest price
Price 2: 4.0
Price 3: 5.0
Price 4: 6.0
Price 5: 3.0 *** lowest price
Price 6: 4.0
Price 7: 5.0
Price 8: 6.0
Price 9: 3.0 *** lowest price
Price 10: 4.0
frilled.cs.indiana.edu%

Looks good. I thought so too.

How do you copy an array? How do you copy a Rectangle?

Array variables work just like object variables. They hold a reference to the actual array.

If you copy the reference, ... you get another reference to the same array.
double[] prices = new double[10];
// ... fill array
double[] copy;
copy = prices;  

Both prices and copy ... point to the exact same thing.

If you were to change copy[i] ... you would see the change in prices[i]

... and that's because both copy and prices ... are different names for one and the same array.

Here's a picture: I like that.

If you want to make a true copy of an array, you must make a new array ... of the same length as the original,

... and copy over all values. Like this?
double copy[] = new double[prices.length];
for (int i = 0; i < prices.length; i++) 
  copy[i] = prices[i];

Yes. You can specify the size of the array through any integer-valued expression, ... so prices.length works just fine.

Instead of the for loop you can also use the System.arrayCopy method. It will be my pleasure to look it up in the API.

Writing the for loop should also be pleasurable. Plus I need to practice.

How do you initialize an array? Like we did above.

Indeed, we can allocate it, then fill each entry. What if we know the elements at the time we write the program?

Then there's an easier way. You can list all the elements that you want to include in the array,

... enclosed in braces, ... and separated by commas.
int[] primes = { 2, 3, 5, 7, 11 };

Can we do it in two steps? Try it.
int[] primes;
primes = { 2, 3, 5, 7, 11 };

Can you also tell me why? What was the error message?

Then the answer is: no. And we need to remember that array constants can be used only in initializers.

Sounds good so far. Now a challenge.

What is it? Could you improve Price.java to behave in the following way:
frilled.cs.indiana.edu%java Price
How many prices?
3
Please enter the 3 prices.
Enter1> 3.45
Enter2> 1.20
Enter3> 6.34
Thank you!
*** Lowest price computed.
Here are the prices: 
Price 1: 3.45
Price 2: 1.2 *** lowest price
Price 3: 6.34
frilled.cs.indiana.edu%

I could try. Here's the solution, just in case.
class Price {
    public static void main(String[] args) {
	ConsoleReader c = new ConsoleReader(System.in); 
	System.out.println("How many prices?"); 
	int size = c.readInt(); 
	double[] price = new double[size]; 
	System.out.println("Please enter the " + size + " prices."); 
	for (int i = 0; i < size; i++) {
	    System.out.print("Enter" + (i + 1) + "> ");  
	    price[i] = c.readDouble();
	    // the user presses enter!
	}
	System.out.println("Thank you!"); 
	double lowest = price[0]; 
        for (int i = 0; i < price.length; i++) {
	    if (price[i] < lowest) {
		lowest = price[i]; 
	    } 
	} 
	System.out.println("*** Lowest price computed."); 
	System.out.println("Here are the prices: "); 
	for (int i = 0; i < price.length; i++) {
	    System.out.print("Price " + (i + 1) + ": "); 
            System.out.print(price[i]); 
            if (lowest == price[i]) {
		System.out.println(" *** lowest price");
	    } else {
		System.out.println(); 
	    } 
	}
    } 
} 

I have a feeling of deja vu. And I was the first to say that.

Last updated: Mar 4, 2002 by Adrian German for A201