|
First Summer 2004
|
Lecture Notes Seventeen: Java arrays.
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 double s.
|
We use the square brackes ([] ) to denote array.
|
So an array of double s 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?
|
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 Rectangle s too?
|
Of course, how many Rectangle s do you anticipate you might later need?
|
|
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 String s.
|
Why String s?
|
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 String s.
|
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?
|
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: May 16, 2004 by Adrian German for A201