CS
99
Summer
2001 7.30
Lecture Notes 9
Reading
6.1, 6.2 Savitch
Introduction to Data Structures
·
Earlier,
we talked about how any algorithm can be expressed in terms of the three
fundamental programming constructs: direct sequencing, conditional branching,
and conditional looping.
·
Just
as important as these language constructs, however, is a language's means of
storing data.
·
So
far we've learned how to declare and create individual variables.
·
A
variable can be viewed as a small box, or cell, in which a single item can be
kept.
·
But
sometimes we need a way to refer to many variables in a uniform manner.
·
Consider
the following class definition that models the students in a classroom:
class ClassRoom {
String
student1, student2, student3, student4, student5;
public
void printStudents() {
System.out.println("Class
roster: ");
System.out.println(student1);
System.out.println(student2);
System.out.println(student3);
System.out.println(student4);
System.out.println(student5);
}
public
String getStudent( int n ) {
String
pupil;
switch ( n ) {
case
1: pupil = student1; break;
case 2: pupil = student2;
break;
case 3: pupil = student3;
break;
case 4: pupil = student4;
break;
case 5: pupil = student5;
break;
default: pupil = null; break;
}
return
pupil;
}
}
·
Every
ClassRoom object created from this blueprint will have 5 students in it. Look how dependent the methods are on the
way we declared the variables! We have to refer to each of the variables by
their unique names.
·
If
we were to modify the class definition so that it has 10 students instead of 5,
we would have to change each and every method: 5 more println statements in the
first method, and 5 more cases in the second.
This is crazy!
·
This
is not a problem with the fundamental programming constructs, but with the way
we store the data.
·
What
we need here is a kind of list for
the student variables that can be "run through", or accessed in some
other way, without the need to name each of the students explicitly.
·
Is
there a way for us to do that? Yes.
Arrays
·
An
array is a simple but powerful programming language construct that can be used
to group and organize data. Almost
every programming language has a way to create arrays or something very much
like it.
·
An
array is a list of values; each value is stored at a specific, numbered
position in the array.
·
If
a variable is like a single hotel room, then an array can be thought of as an
entire corridor, or floor, in a hotel.
Declaring and instantiating
arrays
·
How
do we declare and use arrays?
·
In
Java, arrays are objects. To create an
array, the reference to the array must be declared.
·
An
array reference is declared just like any other reference, but with square
brackets to let Java know that it’s an array:
int[] a; // reference to an array of ints called a
double[] y; // reference to an array of doubles called y
char[] c; // reference to an array of chars called c
·
The
array can then be instantiated using the new
operator, which allocates memory space to store the values.
·
So
to instantiate an array called height comprised of 10 int variables we would write the
following:
int[] height = new int[ 10 ];
·
It's
important to understand that even though we've created a single
"array" called height, we've actually also created 10 new int variables. What’s great is that we can access all those
10 int
variables through a single “handle” called height.
Accessing elements in an
array
·
To
access a value in an array, you use the name of the array followed by the index
in square brackets. Array indices always start at 0. The
index must also be of type int.
·
The
first element in array height is height[ 0 ]; the second, is height[
1 ]; and so
on. The last element in height, because it has only 10
elements, is height[ 9 ].
·
Don't
confuse the value of the index with the value stored in the array at that
index! For instance, the following line
of code assigns 79 to the element at index 8 in array height:
height[ 8 ] = 79;
·
height[ 8 ] is a bonafide int
variable! We don't refer to it the way
we normally would (with a totally unique name) because this particular int variable is a part of a
larger structure, array height.
·
It is illegal to refer to an
element that doesn't exist. So the index must be
positive and < the length of the array.
The length variable
·
Every
instantiated array in Java knows its own length, much like the way String objects do. Only with arrays the length parameter is a
variable, and not a method. We access
the length using the usual dot notation:
height.length has value 10.
·
The
length
variable is very important in programs.
·
Note
too that arrays remain the same size once they are created. However, an array
reference may be reassigned to a new array of a different size at any time.
Array types
·
In
Java, you can create arrays of anything:
String[] sArray = new String[ 50 ];
double[] dArray = new double[ 6 ];
Triangle tArray = new Triangle[ 1000 ];
·
The
first array is an array of 50 String objects, the second is an
array of 6 double
variables, and the last is an array of 1000 Triangle objects.
·
Note
one very important thing! There's a
huge difference between actually creating an array and giving the individual
elements their values. Look at array tArray above. Where in that sentence did we say what the
states of each of the 1000 Triangles in it are? We didn't.
·
When
you instantiate an array the way we do above, all the elements will have their
default values: 0 for ints, 0.0 for doubles, null for objects, false for booleans, etc. So all the elements in arrays sArray and tArray are null, all the elements in dArray have value 0.0.
·
To
actually give them values, you need to write further code.
·
There
is a way to give arrays their values right from the start actually. You can declare arrays using what are called
initializer lists:
int[] a = {1, 2, 3, 4, 5, 6};
Triangle[] tArray = { new Triangle(), new Triangle(3, 4, 5), new Triangle(7, 6,
1) };
·
The
first line creates an array of type int, whose length is 6, whose elements have
the values, a[ 0 ] = 1, a[ 1 ] = 2, …, a[ 5 ] = 6.
·
The
second line creates an array of Triangle objects, whose length is 3, the first
Triangle has sides 0, 0, 0; the second has state 3, 4, 5; and the third, 7, 6,
1.
·
See
the textbook for more details.
ClassRoom Revisited
·
Let's
write our class ClassRoom again, only now let's use arrays to show you how
powerful they can be:
class ClassRoom {
String[]
students;
ClassRoom()
{
students
= new String[ 5 ];
}
ClassRoom(
int n ) {
if
( n > 0 )
students
= new String[ n ];
else
this();
}
public
void printStudents() {
System.out.println("Class
roster: ");
int
count = 0;
while(
count < students.length ) {
System.out.println(
students[ count ] );
count++;
}
}
public
String getStudent( int n ) {
if
( n >= 0 && n < students.length )
return
students[ n ];
else
return
null;
}
}
·
Isn’t
that impressive? Look how much shorter
our algorithms are. Not only are the
algorithms shorter, but they are now
completely general: it doesn’t matter how
many students are in the class. Whether
we have 5 or 1,000,000 students in our array, the methods will work just fine.
·
Notice
too that the methods have exactly the same names. We haven’t changed the services this class provides; we’ve
changed only the way the class stores and manipulates its data.
·
There’s
really not enough time to show you all the cool things we can do with arrays,
but I’ll show you one rather neat thing (it’ll be helpful on tomorrow’s lab).
·
Say
a user was entering in a list of numbers whose values ranged from 0 to 49, and
you wanted to know how many numbers fell in each of the ranges 0-9, 10-19,
20-29, 30-39, 40-49.
·
Because
there are 5 ranges to consider, we should declare an int array with 5 elements
in it; call it freq (for frequency).
·
The
first element, freq[ 0 ] will refer to the first range; the second to the
second range, and so on.
·
Is
there a way to update the array elements without having to use a succession of
if’s and else’s? Yes.
·
Consider
the following code snippet:
int val = in.readInt();
freq[ val/10 ]++;
·
Assuming
that val is a legal value (not < 0 and not > 49), what will happen?
·
Well,
remembering that this is integer division, any number in the range 0-9 when
divided by 10, will become 0; any number in the range 10-19 divided by 10
becomes 1; and so on.
·
In
other words, exactly the right element gets updated when the user enters
in a number from 0 to 49. Isn’t that neat?
No pesky ifs or else. There are
dozens of other tricks like that.
Hopefully, you’ll see them in CS100.
Have
a great summer!