INTRODUCTION TO PROGRAMMING IN JAVA: ARRAY PROCESSING

NOTE: This set of www pages is not the set of www pages for the curent version of COMP101. The pages are from a previous version that, at the request of students, I have kept on line.


CONTENTS

1. Example problem - set I/O
1.1. Requirements
1.2. Analysis
1.3. Design
1.4. Implementation
1.5. Testing
2. Predefined operations on arrays
 
3. Array variables
4. More array processing
4.1. Mapping
4.2. Filtering
4.3. Folding
4.4. Zipping

Notes: (1) The example demonstrates the standard way of manipulating an array by "looping" through the array in such a manner that the loop parameter "doubles" up as the array index (or vice-versa). (2) The "setIO" code presented here is referred back to in the following lecture.




1. EXAMPLE PROBLEM - SET I/O


1.1 Requirements

Design and implement a Java Program to instantiate an eight element set of integers and then output the result. Note: by definition a set cannot contain any duplicates a check will therefore have to be included to ensure this.


1.2 Analysis

Set operations of various sorts are a often used by programmers. Methods to read and output numeric sets are therefore likely to be required at some time in the future. We will therefore create a class SetIO and test this using a application class SetIOtestApp (Figure 1).

The obvious mechanism (data structure) for representing a set is to use an array

 
CLASS DIAGRAM FOR SET IO PROBLEM

Figure 1: Class diagram for set input/output classes


1.3 Design

From Figure 1 we can identify the following methods.

1.3.1 SetIO Class

Field Summary
private static Scanner keyboardInput
           A private class instance to facilitate input from the input stream.
private static final int LOWER_BOUND
           A class constant, set to 0, to mark the start index (lower bound) of the "set" array.
private static final int ARRAY_LENGTH
           A class constant, set to 8 to describe the length of the "set" array.
private int[] integerSet
           An instance field to store an integer array.

Method Summary
public void inputSet()
           Method to allow user to input values for an 8 element integer set. To ensure that no duplicates are included the method incorporates a call to the noDuplicates method (see below). Input is carried out using a while loop which will continue iterating until eight distinct values have been entered.
private boolean noDuplicates(int newElement, int currentEnd)
           Method to check whether a new user supplied value is already contained in the set so far. If so method returns false, otherwise true.
public void outputSet()
           Method to loop through set (using a for loop) and output the values of the set.

5.3.2 SetIOtestApp Class

Method Summary
public static void main(String[] args)
           Main method to test set operations.

A series of Nassi Shneiderman Tables describing the above methods are given in Figure 2 and an accompanying activity diagram in Figure 3.

NASSI SHNEIDERMAN CHARTS FOR SET OPERATIONS PROBLEM

Figure 2: Nassi Shneiderman charts for set I/O problem

ACTIVITY DIAGRAM FOR SET OPERATIONS PROBLEM

Figure 3: Activity diagram for set I/O problem


1.4. Implementation

The implementation for the above is presented in Tables 1 and 2. Note (in Table 2) that we include a "throws" clause in the main method because the inputSet method called may produce an "IO exception".

// SET OPERATIONS
// Frans Coenen
// 28 June 1999
// Revised: Tuesday 30 august 2005
// Dept Computer Science, University of Liverpool

import java.util.*;

class SetIO {

    // ------------------ FIELDS ------------------------

    private static Scanner keyboardInput = new Scanner(System.in);
    private static final int LOWER_BOUND = 0;
    private static final int ARRAY_LENGTH = 8;   
    private int[] integerSet = new int[ARRAY_LENGTH];
		
    // ------------------ METHODS ------------------------

    /* Input a set of elements */

    public void inputSet() {
	int loopParameter = LOWER_BOUND;
	int newElement;
	
	// Loop till set instantiated
	
	System.out.println("Enter " + ARRAY_LENGTH + " elements.");
	while (loopParameter < ARRAY_LENGTH) {
	    newElement = keyboardInput.nextInt();
	    if (noDuplicates(newElement,loopParameter)) {
	    	integerSet[loopParameter] = newElement;
		loopParameter++;
		}
	    else System.out.println("Duplicate element " + newElement);
	    }
	}
	    
    /* ------ NO DUPLICATES ------ */
    
    /* Check for duplicates, return true if non found, false otherwise. */
    
    private boolean noDuplicates(int newElement, int currentEnd) {
        boolean noDuplicatesFound = true;
	
	// Loop through array so far
	    
	for (int index=LOWER_BOUND;index < currentEnd;index++) {
	    if (integerSet[index] == newElement) return(!noDuplicatesFound);
	    }
	
	// Return
	
	return(noDuplicatesFound);
	}
    
    /* OUTPUT CONTENTS OF SET */
    
    public void outputSet() {
    	
	// Commence output
	
	System.out.print("{" + integerSet[0]);
	
	// Loop through rest of set outputting on each iteration 
	
	for(int index=LOWER_BOUND+1;index < ARRAY_LENGTH;index++) {
	    System.out.print("," + integerSet[index]);
	    }
	    
	// End output
	   
    	System.out.print("}");
	}
    }

Table 1: Set operations class implementation

// SET IO TEST APPLICATION
// Frans Coenen
// 28 June 1999
// Revised: Tuesday 30 august 2005
// Dept Computer Science, University of Liverpool

class SetIOtestApp{

    // ------------------- FIELDS ------------------------ 
        
    // None
        
    // ------------------ METHODS ------------------------  
    
    /* Main method */
    
    public static void main(String[] args) {
	// Create instance of SetIO class using default constructor
	SetIO newSet = new SetIO();
	
        // Input values for set 

	newSet.inputSet();
	
	// Output values for set
	
	newSet.outputSet();
	System.out.println("\n");
	}
    }

Table 2: Set operations test application implementation


1.5. Testing


1.5.1. Black Box Testing

BVA, Limit and Arithmetic Testing: Inputs may range from the maximum to the minimum default range for the integer type. We should also include a zero test value. A suitable set of black box test cases is given in the table given to the right.

TEST CASEEXPECTED RESULT
Input setOutput
-2147483649 ... DATA ERROR
2147483648 ... DATA ERROR
-2147483648 -2147483647 0 2147483646 2147483647 ... {-2147483648,-2147483647,0,2147483646,2147483647,...

1.5.2. White Box Testing

Path Testing: We should test each path through the code. More particularly we should test where:

  1. Input is a duplicate and
  2. Input is not a duplicate (of the previous inputs).

A suitable test "input set" would then be of the form given in the table right. Note that we replace the duplicate 0 with a 1.

TEST CASEEXPECTED RESULT
Input setOutput
0 2 3 0 1 7 -2 ...{0,2,3,1,7,-2, ...}

1.5.3. Data validation testing

This should also be done.




2. PREDEFINED OPERATIONS ON ARRAYS

Some programming languages supports a number of predefined operations that can be applied to arrays. For example equality checking or concatenation. Java does not provide such operators. Java also does not support the concept of sub-arrays (sometimes referred to a slices) where a sub-array can be handled as an independent (compound) data item.




3. ARRAY VARIABLES

Some imperative languages also supply a set of predefined variables (sometimes called attributes) describing various features of arrays (and indeed other data types). Typically such variables describe features such as the lower bound, upper bound and length of an array. In Java the only array variable available is length. To use this we must use the dot operator to link it to appropriate array. Thus:

int numberOfElements = 
        myArray.length;
 

will assign the number of elements in the array myArray to the integer data item numberOfElements. The length can be usefully used when processing arrays as shown in the example given in Table 3 where the array is processed without explicitly needing to know it length (size). The output from this code will be as follows:

doubleArray = 
        {0.1, 2.3, 4.5, 6.7, 8.9}  
// USE OF ARRAY LENGTH EXAMPLE
// Frans Coenen
// Tuesday 13 April 1999
// The University of Liverpool, UK
   
class ArrayLengthEx { 

    // ------------------ METHODS -----------------------
    
    /* Main method  */

    public static void main(String[] args) {	
        double[] doubleArray = {0.1,2.3,4.5,6.7,8.9};
	int index=1;
	
	// Output
	
	System.out.print("doubleArray = {" + doubleArray[0]);
	while(index < doubleArray.length) {
		System.out.print(", " + doubleArray[index]);
		index++;
		}
	
	// End
		
	System.out.println("}\n");
	}
    }

Table 3: Use of length variable




4. MORE ARRAY PROCESSING

We can identify a number of common operations that we may wish to perform on arrays: (1) Mapping, (2) Filtering, (3) Folding and (4) Zipping. The terminology used here is that used in declarative languages (logic and functional) to describe list handling operations. However, as arrays can be thought of as lists of elements, it seems appropriate to adopt this classification of list operations to describe common array operations. We will consider each of these operations in the following sub-sections and give an example method to be included in the Set I/O class described above.



4.1. Mapping

It is often necessary to carry out a particular operation on all the members of an array. This is called mapping, we "map" the desired operation onto the elements of the array. For example we may wish to cube all the elements of a set (our integer array defined above) as shown in the Nassi-Shneiderman chart given in Figure 4 and the method in Table 4.

 
NASSI-SHNEIDERMAN CHART

Figure 4: Nassi-shneiderman chart for cube mapping method

/* ------ MAP CUBE ------ */
    
    /* Cube each element of the array */
    
    public void mapCube() {
    	int index;
	
	// Loop through set array and cube each element 
	
	for(index=LOWER_BOUND;index < integerSet.length;index++) 
	    integerSet[index] = integerSet[index] * integerSet[index] *
	    					integerSet[index];
	} 

Table 4: Cube mapping method



4.2. Filtering

The process of running through an array and "keeping" only those elements which pass some test is referred to as filtering. For example identifying the odd numbers in a set (integer array). A suitable SetIO method to carry this out is presented in Table 5 (associated Nassi-Shneiderman chart in Figure 5).

 
NASSI-SHNEIDERMAN CHART FILTER METHOD

Figure 5: Nassi-shneiderman chart for odd number filter method

/* ------ ODD NUMBER FILTER ------ */
    
    /* Loop through set array and output only those elements that represent 
    an odd number */
    
    public void oddNumberFilter() {
    	int index, commaFlag=0;
	
	// Loop through set array and cube each element 
	
	System.out.print("Odd numbers = {");
	for(index=LOWER_BOUND;index < integerSet.length;index++) {
	    if (integerSet[index]%2 == 1) {
	    	if (commaFlag == 1) System.out.print("," + 
						integerSet[index]);
		else {
		    System.out.print(integerSet[index]);
		    commaFlag=1;
		    }
		}
	    }	
	    
	// End
	
	System.out.println("}");    
	}

Table 5: Odd number filter method



4.3. Folding

The process of putting an operator between each pair of elements in an array to produce a single data item is called folding. For example adding up all the elements of a numeric array (set) for the purpose of finding (say) an average value or a total value. An example average method and associated Nassi-Shneiderman chart are presented in Table 6 and Figure 6,

 
NASSI-SHNEIDERMAN CHART FOR FOLDING METHOD

Figure 6: Nassi-shneiderman chart for average method

/* ------ AVERAGE ------ */
    
    /* Loop through set array and determine the total represented 
    by the sum of all the elements. */
    
    public double average() {
    	int index, total=0;
	
	// Loop through set array and add value of each element to total 
	
	for(index=LOWER_BOUND;index < integerSet.length;index++) 
	    total = total + integerSet[index];
	    
	// Return
	
	return((double) total/(double) integerSet.length);  
	}

Table 6: Average method



4.4. Zipping

The process of combining two arrays to form a third is called zipping. For example we may wish to add the elements of two arrays to each other to form a third array (Table 7 and Figure 7).

 
NASSI-SHNEIDERMAN CHART FOR ZIP METHOD

Figure 7: Nassi-shneiderman chart for zip method

/* ------ ZIP ------ */
    
    /* Loop through two given set arrays to form a new array. */
    
    public void zip(SetIO set1, SetIO set2) {
    	int index;
	
	// Loop through set arrays and combine each pair of elements
	// to form a new element 
	
	for(index=LOWER_BOUND;index < set1.length;index++) 
	    integerSet[index] = set1.integerSet[index] +
	    				set2.integerSet[index];
	}

Table 7: Zip method




Created and maintained by Frans Coenen. Last updated 10 February 2015