F21SF Software Engineering Foundations Arrays The java basic array type Dept of Computer Science 09/04/2015 Monica Farrow EM G30 email : M.Farrow@hw.ac.uk Material available on Vision SEF Arrays 1 1 Topics Using the basic java array type to keep lists of integers and Strings. With an array Adding a value for a specified position Traversing the elements in the array, using length variable Returning a String containing details Returning a total Returning maximum Searching, using 2 algorithms 09/04/2015 SEF Arrays 1 2 Arrays Arrays are fixed-length structures for storing multiple values of the same type. They are useful for keeping lists of items All items must be of same type E.g. int, double, char, String, Name, Car…… In java, an array is a special kind of class, with a unique syntax First we will consider arrays of integers, as an example of arrays of primitive types. The array can be declared by adding the array symbol [ ] before or after the variable name int [] marks; 09/04/2015 String [] prevQuals; SEF Arrays 1 3 Instantiating an array - 1 If the values initially are not known, instantiate the array using new and the length. This defines the size only, not the contents. Each element has a default value, which is 0 for integers, null for objects final static int NUM_MARKS = 5; marks= new int [NUM_MARKS]; NUM_MARKS= 5 index 09/04/2015 0 0 0 0 0 0 1 2 3 4 SEF Arrays 1 4 Instantiating an array - 2 If the values are known, the array can be declared and instantiated like this: prevQuals = { “MIC”, “ARA”, “FAC”}; (fictitious previous qualifications) The size of this array is determined by the number of values supplied within the curly braces MIC index 09/04/2015 0 ARA FAC 1 2 SEF Arrays 1 5 Elements in the array Consider the elements in the marks array as 5 separate variables called marks[0], marks[1], marks[2], marks[3], marks[4] Indexing the items (numbering like Strings) The first index is 0 The last index is one less than the number of entries in the array The ith element is stored using index i-1 09/04/2015 first element : marks[0], third element : marks[2] SEF Arrays 1 6 Accessing individual items Storing data into an element of the array marks[0] = 2; Extracting data from an element of the array System.out.println(marks[3]); int lastMark = marks[4]; 09/04/2015 SEF Arrays 1 7 (Recap: Accessing instance variables) Instance variables describe each particular object E.g Car : model, tank size, mpl…. Usually private, so accessed only using a ‘get’ method myCar.getModel() This separates the ‘interface’ of the class (i.e. what methods can you use) from the implementation (how it is actually done) IF they were public, they could be accessed using the object name and a period myCar.model 09/04/2015 SEF Arrays 1 8 Finding the length of an array You can use the array public length instance variable directly i.e. marks.length NB this is NOT a method, so no brackets VERY confusing Strings have a length method Arrays have a public length instance variable 09/04/2015 SEF Arrays 1 9 Traversing items in a list The index can be calculated at runtime Elements can be accessed using an index value which is in a variable int index = 4; int value = marks[index]; The index in the variable can be increased by one each time, to enable iteration through the array for ( int index = 0; index < marks.length; index++) { System.out.println(marks[index]); } 09/04/2015 SEF Arrays 1 10 Problems : Array Index Out of Bounds Your program crashes with an ArrayOutOfBoundsException if you use an index that is greater than or equal to the length of the array E.g. marks[6] = 10; The error message tells you the index number and the program line number that is causing the problem E.g. Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6 at Student.addMark(Student.java:30) at MainStudent.main(MainStudent.java:12) 09/04/2015 SEF Arrays 1 11 Problems: Assigning memory to an array When an array is initially declared, a small amount of space is allocated to it to hold a ‘pointer’. This is true for all objects in java. The pointer is the address in memory of the full details for the object, and is initially null marks Points nowhere Memory is only allocated once the array is instantiated (with new or with literal values ) marks 09/04/2015 Points to details SEF Arrays 1 1 3 0 9 8 12 Problems : Null pointer exception You can get a null pointer exception by not instantiating the array. In a simple example with just a main method, the program will not compile if you just declare the array without instantiating it However, in more complex programs with more classes and methods, the program may compile. It will then crash with a null pointer exception if you refer to a specific item in the un-instantiated array. 09/04/2015 SEF Arrays 1 13 Student example In this program, we want to store, for a student, their id, name, year of study, previous qualifications and marks. Previous qualifications is a list of Strings. Each student may have a different number of qualifications. The number is fixed for a student – once the qualifications have been supplied, they won’t change. A set of 3 marks, initially all 0. The marks can be inserted during the program run. We would like to Add a mark for a specified assignment (numbered 1, 2 and 3) Obtain a summary message for each student E.g. “Helen Scott has an average mark of 6.3, highest mark is 8. Qualifications: MIC ARA” 09/04/2015 SEF Arrays 1 14 One possible Class Design using CRC cards MainStudent Responsibility Collabor ators Creates a couple of students Prints student reports to Standard output Changes one value Adds a mark Student Student Responsibility Holds id, name, year of study Holds list of previous qualifications Holds list of marks Add a mark for a specified assignment Returns id, name, year (in 3 methods) Returns a marks average Returns a mark maximum Returns a list of qualifications 09/04/2015 SEF Arrays 1 15 Class Diagram MainStudent main(arg[] : String) : void Student id : String name : Name year:int prevQuals : String [] marks : int[] Student(id:String, name:Name, pq:String [], year:int) getId() :String getName() : String addMark(value:int, ass:int) : void getAveMark() : double getMaxMark() : int getQualList() : String 09/04/2015 SEF Arrays 1 16 Student class public class Student { private String id; //unique id, e.g. 0099 private Name name; private int year; //year of study e.g. 1,2,3 etc private String [] prevQuals; //previous qualifications private static final int NUM_MARKS = 3; private int [] marks; //marks for the module - 5 assignments //qual array is provided as a parameter //marks array is initialised to a fixed size public Student (String id, Name n, String [] pq, int y) { this.id = id; name = n; prevQuals = pq; year = y; marks = new int [NUM_MARKS]; // initially all 0 } 09/04/2015 SEF Arrays 1 17 Creating a student object in main method The qualification array is declared with known values, and here will have length = 2 The marks array is created in the constructor, of length 3, and all values start as 0 (the default for integers) String [] quals1 = {"MIC", "ARA" }; Student s1 = new Student ("0011", new Name("Helen Scott"), quals1, 1); 09/04/2015 SEF Arrays 1 18 Adding marks The method to add marks in the Student class Assignments are numbered 1,2,3 Arrays are numbered 0,1,2 public void addMark(int value, int ass ) { int index = ass-1; marks[index] = value; } Adding marks from main method s1.addMark(8,1); s1.addMark(7,2); s1.addMark(4,3); 09/04/2015 SEF Arrays 1 19 Producing details as a String This method produces a String, adding in the location. It then traverses the array, accessing each element in turn, and adding the value to the String. public String getQualDetails() { String report = "" ; for (int qualsIndex = 0; qualsIndex < prevQuals.length; qualsIndex++) { report += prevQuals[qualsIndex] + " "; } return report; } 09/04/2015 SEF Arrays 1 20 Finding the average //add up all the marks, then divide by number of marks //demonstrates forcing double division //assumes that all marks entered, or, if not, ok to use 0 for calculation public double getAveMark() { int total = 0; for (int marksIndex = 0; marksIndex < marks.length; marksIndex++) { total += marks[marksIndex]; } return (double) total/marks.length; } NB Casting total to a double before dividing by an integer 09/04/2015 SEF Arrays 1 21 Finding a maximum Algorithm for finding a maximum The first element becomes the current maximum For each element If the value of this element is greater than the current maximum, Store this value as the current maximum public int getMaxMark() { int max = marks[0]; for (int marksIndex = 1; marksIndex < marks.length; marksIndex++) { if (marks[marksIndex] > max) { max = marks[marksIndex]; } } return max; } 09/04/2015 SEF Arrays 1 22 Testing The getMaxMark() method is a good example of how careful you need to be when testing your program It is very common to make a mistake in your boundary conditions e.g. index = 0; index<limit. Too big and your program will crash (ok, so you find the error pretty quickly) Too small and your program will work but miss out the last value Values like totals and counts and searches will be wrong So it is a good idea to test with the maximum value In the first position In the last position Somewhere in the middle And add up totals yourself, to make sure that the value returned is correct 09/04/2015 SEF Arrays 1 23 Using these methods double ave = s1.getAveMark(); int max = s1.getMaxMark(); System.out.println(s1.getName().getFullName() + " has an average mark of " + String.format ("%.1f", s1.getAveMark()) + " and a highest mark of " + s1.getMaxMark() ); System.out.println("Previous qualifications: " + s1.getQualDetails()); 09/04/2015 SEF Arrays 1 24 Searching Here is a typical way of searching //returns true if the person has the specified qualification, false otherwise //can stop as soon as it is found, //but might get to end and not find it at all. //demonstrates searching and returning as soon as condition is met. public boolean hasQual(String searchQual) { for (int qualsIndex = 0; qualsIndex < prevQuals.length; qualsIndex++) { String prevQual = prevQuals[qualsIndex]; if (prevQual.equals(searchQual) ) { return true; } } return false; } 09/04/2015 SEF Arrays 1 25 Searching with while This method has the same effect as the previous one Uses while condition to stop the loop Useful if you don’t want to return from the method at the end of the loop BUT, if you use the principle ‘one method for one function’, you probably will always be able to use the first version public boolean hasQualification(String searchQual) { int qualsIndex = 0; boolean found = false; while (qualsIndex < prevQuals.length && !found) { String prevQual = prevQuals[qualsIndex]; if (prevQual.equals(searchQual) ) { found = true; } qualsIndex++; } return found; } 09/04/2015 SEF Arrays 1 26 Quiz Look at the Student class and the associated main method What would happen if: the index in the loop in the getMaxMarks() method starts at 0 instead of 1? the test in that loop was <= instead of <? you omitted (double) from the return line in the getAveMarks() method? the addMark() method didn’t subtract one from the assignment number? you had specified that the addMark() method must provide an index position not an assignment number? you added a mark for assignment number 6? You forgot to use the getFullName() method when printing the name in the main method – just using ls.getName() instead? 09/04/2015 SEF Arrays 1 27 The main method Now we can understand the parameter in the main method public static void main (String args[]) The parameter is an array of Strings We probably won’t use the parameter much if at all in this module However, it is there, and could be used for providing runtime data In the example on the next slide, 2 String parameters are provided and are referred to as args[0] and args[1] 09/04/2015 SEF Arrays 1 28 A main method with parameters public class Greetings { public static void main (String args[]) { System.out.println("Hello " + args[0] + " " + args[1]); } } Running at the command line: >javac Greetings.java >java Greetings Sarah Jane Hello Sarah Jane 09/04/2015 SEF Arrays 1 29 Parameters with an IDE You can also enter parameters for the main method when using an IDE such as eclipse You will need to find where this is done For eclipse, you can set them in the Run Configurations dialog box, accessible from the Run menu. 09/04/2015 SEF Arrays 1 30 Multiple arrays You can have arrays of many dimensions. The next example shows 2D arrays Consider the game of ‘noughts and crosses’, where the aim is to get a row of X’s or O’s. O O X X X O X 09/04/2015 SEF Arrays 1 31 2 D arrays : notation Declare a 2D array with the rows first, then the columns char [][] grid = new char [3][3]; 0 1 2 0 1 2 09/04/2015 SEF Arrays 1 32 2D arrays contd Each element needs to have the row and the column specified grid[2][0] = ‘X’; Use nested loops to traverse complete array for(int row=0; row<3; row++) for (int col =0; col<3; col++) grid[row][col] = ' '; Use meaningful indexes e.g. row, col rather than i and j. 09/04/2015 SEF Arrays 1 33 Arrays so far We’ve seen an array of integers and one of Strings Any object can be held in an array Pick it out e.g. String prevQual = prevQuals[qualsIndex]; Use its methods e.g. prevQual.equals(searchQual) Arrays are a fixed size in java You couldn’t easily add more qualifications or increase the number of marks held Next lecture – the java ArrayList class. 09/04/2015 SEF Arrays 1 34 To Do Now Read over lecture and look at code, try running the program Do the quiz You should now be able to add a set of scores to your competitor class. After the next lecture, you will be able to add a collection of competitors. 09/04/2015 SEF Arrays 1 35