ARRAYS

Arrays are "static" entities, as they remain the same size once they are created, although an array reference may be reassigned to a new array of a different size.  An array is a group of contiguous memory locations that all have the same name and the same type.  To refer to a particular location or element, we specify the name of the array and the position number (index or subscript).  The first element in every array has the position number zero.  For an array c, the first element will be c[0], the second element will be c[1], and the ith element will be c[i - 1].    Array names follow the sam conventions as other variable names.  The position number in square brackets is called index or subscript.  This must be an integer or integer expression (constant, variable, or algebraic expression).  For example, if we assume that a is 5 and b is 6, then the statement
c[ a + b ] += 2; will add 2 to the value of the array element c[ 11 ].  The name of the array is c.  Every array in Java knows its own length and maintains this information in a variable called length.  The expression c.length accesses array c's length variable to determine the length of the array.  To calculate the sum of the values contained in the first three elements of array c and store the result in variable sum:    sum = c[ 0 ] + c[ 1 ] + c[ 2 ];  To divide the value of the seventh element of array c by 2 and assign the result to variable x:    x = c[ 6 ] / 2;

Declaring and allocating arrays

Arrays are objects that occupy space in memory.  They must be allocated dynamically with the operator new.  The programmer specifies the type of the array elements and the number of elements.  To allocate 12 elements for the integer array c:    int c[ ] = new int[ 12 ];     Alternatively,    two statements can be used:    int c[ ]; followed by c = new int[ 12 ];
Each element of the array receives a default value-zero for numeric primitive types, false for boolean, and null for references.  A program can allocate memory for several arrays in a single declaration.  String b[] = new String[ 100 ], x[] = new String[27 ];  When declaring an array, the type of the array and the square brackets can be combined at the beginning of the declaration to indicate that all identifiers in the declaration represent arrays:  double[] array1 = new double[ 10 ],
                                                                                                          array2 = new double[ 20 ];
A program can declare arrays of any data type.  Every element of an int array contains an int value.  But every element of a String array is a reference to a String.

There are two ways to allocate an array and initialize its elements.

1.    Using operator new to allocate dynamically.

    int array[];                           // declare reference to an array
    array = new int[ 10 ];            // dynamically allocate array

2.    Using an initializer list to initialize elements of an array

    int n[] = { 10, 20, 30, 40, 50 }

Uses of Arrays

Summing the elements of an Array

Often, the elements of an array represent grades in an exam, which have to be added together to determine the average.  The program segment below explains how this is accomplished.

    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int total = 0

    for ( int counter = 0; counter < array.length; counter ++ )
        total += array[ counter ];

Using Histograms to display data graphically

Numeric values are often displayed as bars in a bar chart using asterisks (*).  The program segment below explains how this is accomplished.

    int array = { 19, 3, 15, 7, 11, 9, 13, 5, 17, 1 }

    for ( int counter = 0; counter < array.length; counter ++ ) {
        output +=
            "\n" + counter + "\t" + array[ counter ] + "\t";
        for ( int stars = 0; stars < array[ counter ]; stars ++ )
            output += "*";
    }

Using the elements of an array as counters

An example is tossing a six-sided die 6000 times and noting the frequency of the value on each face.  The program segment below explains how this is accomplished.

    int face, frequency[] = new int[ 7 ];

    for ( int roll = 1, roll <= 6000; roll++ ) {
        face = 1 + ( int ) ( Math.random() * 6 );
        ++ frequency[ face ];
    }

    for ( face = 1; face < frequency.length; face++ )
        output += "\n" + face + "\t" + frequency[ face];

Using Arrays to survey results

Arrays summarize the results collected in a survey. The program segment below explains how this is accomplished.

    int responses[] = { 1, 2, 6, 4, 8, 5, 9, 7, 8, 10, 1, 6, 3, 8, 6, 10, 3, 8, 2, 7, 6, 5, 7, 6, 8, 6, 7, 5, 6, 6, 5, 6, 7, 5, 6, 4, 8, 6, 8, 10 }
    int frequency[] = new int [ 11 ];

    for ( int answer = 0; answer < response.length; answer ++ )
        ++frequency[ responses[ answer ] ];

    for ( int rating =1; rating < frequency.length; rating++ )
        output += rating + "\t" + frequency[ rating ] + "\n";

References and Reference Parameters

Two ways to pass arguments to methods in most languages are Pass by value (or Call by value) in which in which a copy of the argument's value is made and passed, and pass by reference (or call by reference) in which the caller gives the called method the ability to access the caller's data directly and modify that data if the called method so chooses.  Pass by reference eliminates the overhead of copying large amounts of data.  In Java, arrays are treated as objects, and so passed by reference only.  The reference name is specified in the method call. The name of an array is a reference to an object that contains the array elements, and the length instance variable indicates the number of elements in the array.  To pass an array argument, specify the name of the array without brackets..  If hourlyTemperatures is declared as

        int hourlyTemperatures = new int[ 24 ]; the method call

        modifyArray( hourlyTemperatures); passes hourlyTemperatures to method modifyArray.  Since every object knows its size, the size of the array is not passed.

Entire arrays and objects referred to by individual elements are passed by reference, but individual array elements, called scalars or scalar quantities are passed by value, using the subscripted name of the array element.

Sorting Arrays

Sorting is placing data in ascending or descending order.  There are many techniques.  One inefficient, but easy to understand is called Bubble Sort. (Actually it is Sinking Sort), as smaller values "bubble" to the top (beginning) and larger values "sink" to the bottom (end).  The technique uses nested loops to make several passes through the array, each pass comparing successive pairs of elements.  If a pair is in increasing order (or the values are equal)  the values are unchanged.  Otherwise, the values are swapped.  This is done by moving one value to a temporary location, moving the second value to the location of the first, and then moving the value in the temporary location into the second location.  The program segment below explains how this is accomplished.

    for ( int pass = 1; pass < arrray.length; pass++ ) {
        for (int element = 0; element < array.length; element++ ) {
            if ( array[ element ] > array[ element + 1 ] )
                swap( array, element, element + 1)
        }
    }

    public void swap( int array[], int first, int second )
    {
        int hold;

        hold = array[ first ];
        array[ first ] = array[ second ];
        array[ second ] = hold;
    }

Searching Arrays

Searching determines whether an array contains a certain key value. There are two searching techniques

Linear (also called Sequential) Search:

In this method, sorting in not necessary, although sorting can make this technique more efficient.  It works well for small arrays (less than 20 elements), but not for larger arrays.  The program compares the key with each value in turn and returns either the location or -1 if the value is not found.  If there are n elements, the minimum number of comparisons is 1, if the key is the first element, and the maximum number is n if it is the last, or if the key is not in the array.  The average number is (n + 1) / 2 or approximately n/2.  The program segment below explains how this is accomplished.

    for ( int counter = 0; counter < array.length; counter++ )

        if ( array[ counter ] == key )
            return counter;                        // location of key returned

        return -1                                     // key not found

Sequential Search

For larger arrays (more than 20 elements) this is more efficient.  The elements must first be sorted.  This method eliminates half of the elements in the array being searched after each comparison.  The algorithm locates the middle array element and compares it to the search key.  If they are equal, the search key has been found and the subscript of the element is returned.  Otherwise, if the search key is less than the middle array element, the first half of the array will be searched.  if not, the second half of array will be searched   The middle element of the new smaller array is located and the process is repeated.  The search continues until the search key is the middle element or there is only one element left, in which case, the search key is not found.  If here are 1024 elements, it would require at most 10 searches.  (1024 = 210).  In the case of linear search, the average would be 1024/2 = 512.  An array of a million elements would require 20 searches and that with a billion 30 searches.  The maximum number of comparisons is the exponent of the first power of two greater than the number of elements in the array.  The program segment below explains how this is accomplished.

    int low = 0;                                // low element subscript
    int high = array.length - 1        // high element subscript
    int middle

    while ( low <= high ) {           // loop until low subscript is greater than high subscript

        middle = ( low + high ) / 2

        if ( key == array[ middle ] )
            return middle;               // key found, subscript returned

        else if ( key < array[ middle ] )
           high = middle - 1;         // new high is set one less than old middle

        else
           low = middle + 1;         // new low is set one more than old middle
    }

            return -1;                        // key not found

Multiple-Subscripted Arrays

Double-scripted or Two-dimensional arrays represent tables of values consisting of information arranged in rows and columns.  Two subscripts are specified, the first identifying the row and the second the column.  Java does not support multi-scripted arrays directly, but single-scripted arrays whose elements are also single-scripted arrays can be specified.  Table below shows an example of an array a, consisting of three rows and four columns (a 3-by-4 array)
 
 
 
Column 0
Column 1
Column 2
Column 3
Row 0
a[ 0 ][ 0 ]
a[ 0 ][ 1 ]
a[ 0 ][ 2 ]
a[ 0 ][ 3 ]
Row 1
a[ 1 ] [ 0 ]
a[ 1 ][ 1 ]
a[ 1 ][ 2 ]
a[ 1 ][ 3 ]
Row 2
a[ 2 ][ 0 ]
a[ 2 ][ 1 ]
a[ 2 ][ 2 ]
a[ 2 ][ 3 ]

In general, an array with m rows and n columns is called an m-by-n array.

Initializing and declaration of multi-scripted arrays

A double-scripted array b[ 2 ][ 2 ] could be declared and initialized with
     int b[][] = { { 1, 2 }, { 3, 4 } };  The compiler determines the number of rows by counting the counting the number of initializer sublists (represented by sets of braces - 2 in example above), and the number of columns in each row by counting the number of initializer values in the initializer sublist for that row.  The number of columns in every row need not be the same.  The declaration
    int b[][] = { { 1, 2 }, { 3, 4, 5 } }; creates integer array b with row 0 containing two elements (1 and 2) and row 1 with 3 (3 , 4, and 5).

A multiple-subscripted array with the same number of columns in every row can be allocated dynamically.  For a 3-by-4 array:
 
    int b[] [];
    b = new int[ 3 ][ 4 ];

The elements of a double-subscripted array are initialized when new creates the array object.

If the multi-subscripted array has rows with different number of columns, then:

    int b[] [];
    b = new int[ 2 ][ ];            // allocates two rows
    b[ 0 ] = new int[ 5 ];        // allocates five columns for row 0
    b[ 1 ] = new int[ 3 ];        // allocates three columns for row 1