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.

 

Cool things with arrays

·         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!