Arrays and Array Lists CS 21 a Problem
Arrays and Array Lists CS 21 a
Problem 1: Reversing Input n n Problem: Read in three numbers and then print out the numbers in reverse order Straightforward Java application n public static void main( String[] args ) throws IOException { String temp; double num 1, num 2, num 3; temp num 1 temp num 2 temp num 3 declare three variables of type double read in String values for each of them and convert print them out starting with the last variable read in } = = = console. read. Line(); Double. parse. Double(temp); System. out. println( num 3 ); System. out. println( num 2 ); System. out. println( num 1 );
Generalizing a Program n n Suppose we wanted the same program but wanted 10 instead of 3 numbers? Suppose we wanted to read in 1000 numbers? n n More than 3000 lines of code if we used the same approach! Solution: arrays
Arrays n pronounced “ar-ray”, w/ stress on 2 nd syllable n Definition n collection of elements of the same type each element is accessed through an index In Java, n n n declaration: creation: use: n double[] nums; nums = new double[8]; nums[3] = 6. 6; Note: starting index is 0 (0 to 7, above) double nums[] is also legal, but double[] nums is preferred, since it emphasizes that the type is double[] (“double array” or “array of doubles”)
Visualizing an Array nums null Declare: double[] nums;
Visualizing an Array nums null Declare: double[] nums; Create: nums = new double[8]; 0 0. 0 1 0. 0 2 0. 0 3 0. 0 4 0. 0 5 0. 0 6 0. 0 7 0. 0
Visualizing an Array nums Declare: double[] nums; Create: nums = new double[8]; Use: nums[3] = 6. 6; 0 0. 0 1 0. 0 2 0. 0 3 6. 6 0. 0 4 0. 0 5 0. 0 6 0. 0 7 0. 0
Reversing 10 numbers n Use arrays and loops n n declare double[] nums create new double[10] use a for-statement to read in the numbers use a for-statement to print them out in reverse public static void main( String[] args ) throws IOException { double[] nums = new double[10]; for ( int i = 0; i < 10; i++ ) { String temp = console. read. Line(); nums[i] = Double. parse. Double(temp); } } for ( int i = 9; i >= 0; i-- ) { System. out. println( nums[i] ); }
Scaling up n What if you want to change the number of elements? n n public static void main( String[] args ) throws IOException { double[] nums = new double[10]; for ( int i = 0; i < 10; i++ ) { String temp = console. read. Line(); nums[i] = Double. parse. Double(temp); } would have to find and change all places using 10 (including the 9 in the for loop) very tedious and error -prone } for ( int i = 9; i >= 0; i-- ) { System. out. println( nums[i] ); }
Using Constants n What if you want to change the number of elements? n n n would have to find and change all places using 10 (including the 9 in the for loop) very tedious and error -prone public class Reverse. Array { … public static final int MAX = 10; public static void main( String[] args ) throws IOException { double[] nums = new double[MAX]; for ( int i = 0; i < MAX; i++ ) { String temp = console. read. Line(); nums[i] = Double. parse. Double(temp); } Solution: use a constant } for ( int i = MAX - 1; i >= 0; i-- ) { System. out. println( nums[i] ); }
Using Constants n n A constant has to be a class-wide variable (not a local variable) Important keywords n n n static -- means value is shared by all instances (more later) final -- means value can’t be changed (i. e. , it’s a constant) public class Reverse. Array { … public static final int MAX = 10; public static void main( String[] args ) throws IOException { double[] nums = new double[MAX]; for ( int i = 0; i < MAX; i++ ) { String temp = console. read. Line(); nums[i] = Double. parse. Double(temp); } Capitalization n ALL_CAPS, words separated by underscore } for ( int i = MAX - 1; i >= 0; i-- ) { System. out. println( nums[i] ); }
Constants and “Magic Numbers” n Constants are useful for “magic numbers” – i. e. , specific values that are used throughout the code n n e. g. , MAX_LENGTH, SCREEN_WIDTH, PI, BLUE, DASHED_LINE, etc. Useful because n makes code more readable and maintainable n n e. g. , WHITE is easier to understand easier to remember than 255 makes modifications easier n e. g. , in reversing program example, we just need to change MAX. No need to look for 10 and 9 and change them.
Problem 2: Collection of Objects n How can we write Bank so it can handle a larger number of Bank. Accounts? n Right now, we can only handle a small number of accounts (2 or 3) withdraw( “Alice”, “ 1234”, 200 ) get. Balance( “Bob”, “ 4321” )
Solution: Array of Objects n Declaration n n Creation of the Array n n Bank. Account[] accounts; accounts = new Bank. Account[5]; creates an array of references to Bank. Accounts but no actual Bank. Accounts yet Creation of Objects n n for ( i = 0; i < 5; i++ ) { accounts[i] = new Bank. Account(); } creates the Bank. Accounts themselves and assigns these to the references
Visualizing an Array of Objects accounts null Declare: Bank. Account[] accounts;
Visualizing an Array of Objects Bank. Account-type references accounts null Declare: Bank. Account[] accounts; Create array: accounts = new Bank. Account[5]; 0 null 1 null 2 null 3 null 4 null
Visualizing an Array of Objects Bank. Account-type references acounts null Declare: Bank. Account[] accounts; Create array: accounts = new Bank. Account[5]; Create objects: for ( i = 0; i < 5; i++ ) { accounts[i] = new Bank. Account(i * 10); } 0 null 1 null 2 null 3 null 4 null Bank. Account balance 0 Bank. Account balance 10 Bank. Account balance 20 Bank. Account balance 30 Bank. Account balance 40
Visualizing an Array of Objects Bank. Account-type references acounts null Declare: Bank. Account[] accounts; Create array: accounts = new Bank. Account[5]; Create objects: for ( i = 0; i < 5; i++ ) { accounts[i] = new Bank. Account(i * 10); } Use objects: e. g. , accounts[3]. get. Balance(); 0 null 1 null 2 null 3 null 4 null Bank. Account balance 0 Bank. Account balance 10 Bank. Account balance 20 Bank. Account balance 30 (returns 30) Bank. Account balance 40
Approach n Include a name field in Bank. Account n Create set and get methods for this field n Declare an array of Bank. Account objects n Use a loop in the find. Account() method of Bank
Approach n n n A field representing the acct name has been added: acct. Name public class Bank. Account { private double balance; private String acct. Name; Constructor has been modified to accept an initial balance Set and get methods were created to access acct. Name } public Bank. Account( double init. Balance ) { balance = init. Balance; } public void set. Acct. Name( String name ) { acct. Name = name; } public String get. Acct. Name() { return acct. Name; } …
Approach n n n A field representing an array of Bank. Accounts was added: accounts public class Bank { private Bank. Account[] accounts; private static final int MAX = 10; There is also a constant representing the maximum amount of bank. Accounts bank can handle: MAX The array is initialized in the constructor. It is also populated with 2 Bank. Account objects named “john” and “marsha” … } public Bank() { accounts = new Bank. Account[MAX]; accounts[0] = new Bank. Account(100); accounts[0]. set. Acct. Name(“john”); accounts[1] = new Bank. Account(200); accounts[1]. set. Acct. Name(“marsha”); }
Approach n n find. Account contains a forstatement that searches for the appropriate account The get. Name() method of an account is used to get the name and compare it with the name parameter public class Bank { … private Bank. Account find. Account( String name ) { for( int x = 0; x < MAX; x++ ) { if( accounts[x]. get. Acct. Name(). equals(name) ) { return accounts[x]; } } Be careful when writing code return null; like this. Doing this gives a } Null. Pointer. Exception if no … Bank. Account instance is } assigned to that location.
Approach n n public class Bank { … A reference to the private Bank. Account find. Account( String name ) correct account is returned when it is { for(int x = 0; x < MAX; x++) found, otherwise { the value returned if ( accounts[x] != null ) is null { if( accounts[x]. get. Acct. Name(). equals(name) ) A return statement { is put inside the for return accounts[x]; -statement to } “break out” of the } loop when the One possible alternative as } correct account has this first checks if the return null; been found location contains an instance } of Bank. Account (i. e. , not null) … }
Approach public class Bank { … private Bank. Account find. Account( String name ) { for(int x = 0; x < num. Accounts; x++) { if( accounts[x]. get. Acct. Name(). equals(name) ) { return accounts[x]; } } Another possible alternative is return null; to change the limit of x to the } actual number of accounts the … array contains. }
Approach n What is the value of num. Accounts? public class Bank { private Bank. Account[] accounts; private static final int MAX = 10; private int num. Accounts = 0; … } public Bank() { accounts = new Bank. Account[MAX]; accounts[0] = new Bank. Account(100); accounts[0]. set. Acct. Name(“john”); accounts[1] = new Bank. Account(200); accounts[1]. set. Acct. Name(“marsha”); num. Accounts = 2; }
Creating new Bank. Accounts public void open. Account( String name, int initbal ) { if ( num. Accounts < MAX ) { accounts[num. Accounts] = new Bank. Account( initbal ); accounts[num. Accounts]. set. Acct. Name( name ); num. Accounts++; } else { System. out. println( "Maximum number of accounts reached" ); } }
Using open. Account as a convenience method n In the Bank’s constructor: public Bank() { accounts = new Bank. Account[MAX]; } open. Account( "john", 1000 ); open. Account( "marsha", 2000 );
More About Arrays n Arrays are objects n n the array variable is just a reference to the actual array that contains the values need to use “new” after declaring passed as a reference when used as method parameter Special features n a public final int length field returns the array size n n in recent example, accounts. length would return 10 [] operator only work with arrays
More About Arrays n Array. Index. Out. Of. Bounds exception n valid indices for array of size n: 0 to n-1 any access to other indices causes an error Array size can’t be changed after array is created n To expand array, we need to create a new array, copy old array contents, then point array variable to new array
Array Initializers n n n You can initialize an array with the following syntax: String[] responses = { “Hello”, “Hi”, “How are you”, “How do you do” }; Can be used for fields, local variables, and even constants
Useful Pattern n Put different responses for different cases in an array n n Assign an integer to represent different cases n n String[] responses = { “Hello”, “Hi”, “How are you”, “How do you do” }; In this case 0 means the program will say “Hello”, 1 means it will say “Hi”, etc. Now you can generate the data for each case accordingly n n e. g. , What does the following code do? int greeting. Case = Math. random() * responses. length; String greeting = responses[greeting. Case] + “World”; System. out. println( greeting );
Multi-dimensional Arrays (Optional) n A natural extension of simple (1 D) arrays n n n 2 D declaration: char[][] grid; think “array of arrays” Array creation grid = new char[10][20]; // 10 rows, 20 columns n Another way grid = new char[10][]; // creates array of 10 char[]’s for (i = 0; i < 10; i++) { grid[i] = new char[20]; // creates a size-20 array } n This way allows for varying row sizes
Visualizing 2 D Arrays char[]-type references char[][] 0 1 null Declare: char[][] grid; Create array of rows: 3 4 grid = new char[5][]; Create rows: for ( i = 0; i < 5; i++ ) { grid[i] = new char[3]; } Use objects: 2 e. g. , grid[3][2] = ‘C’ C
Using 2 D Arrays n To refer to individual element, use two indices n n Using only one index refers to a single dimensional array n n n e. g. , grid[2][1] = ‘X’; e. g. , grid[4] refers to row 4 grid[4]. length is the length of row 4 (in this case, it’s 3) The array variable by itself refers to the top-level array (i. e. , the array of rows) n grid. length is the length of the array of rows (i. e. , it’s the number of rows)
Problem 3, Flexible collections n How can we write Bank so it can have an arbitrary number of Bank. Accounts? n Right now, we can only handle a small and fixed number of accounts (2 or 3) withdraw( “Alice”, “ 1234”, 200 ) get. Balance( “Bob”, “ 4321” )
The Java Collections Framework n n n A set of classes that you can use for containing arbitrarily large collections of objects To use, you must say import java. util. *; at the top of your code Some basic Collections classes n n Array. List, Vector Hash. Map, Hashtable
Array. List n Array. List<String> names Indexed list of objects that automatically resizes n n The list is ordered, with each object in the list having an index, from 0 to n-1 Most commonly used methods n n n boolean add( E element ) int size() E get( int index ) E set( int index, E element ) plus others (see API docs) Array. List 0 “Bart” 1 “Lisa” 2 “Maggie” Note: Array. Lists in Java 5 is used slightly differently from its previous versions.
Array. List Example import java. util. *; Array. List<String> public class Array. List. Demo 1 You have to specify { the type of object public void execute() it has to store. { Array. List<String> names = new Array. List<String>(); names. add( "Bart" ); Array. List names. add( "Lisa" ); names. add( "Maggie" ); 0 for ( int i = 0; i < names. size(); i++ ) { 1 System. out. println( names. get( i ) ); } 2 names. set( 1, "Homer" ); names. add( "Marge" ); 3 for ( int i = 0; i < names. size(); i++ ) { System. out. println( names. get( i ) ); } } } names “Bart” “Homer” “Lisa” “Maggie” “Marge”
Using Other Types Array. List accts import java. util. *; public class Array. List. Demo. With. Bank. Accounts { public void execute() { Array. List<Bank. Account> accts = new Array. List<Bank. Account>(); accts. add( new Bank. Account( 2000 ) ); accts. get(0). set. Acct. Name(“Alice”); accts. add( new Bank. Account( 1000 ) ); accts. get(1). set. Acct. Name(“Bob”)); for ( int i = 0; i < accts. size(); i++ ) { Bank. Account cur. Account = accts. get( i ); Bank. Account int balance Array. List } } String name “Alice” 0 1 System. out. println( "Bank Account #" + i + "Owner: " + cur. Account. get. Acct. Name() + ", " + "Balance: " + cur. Account. get. Balance() ); } 2000 Bank. Account int balance 1000 String name “Bob”
Looping through Array. Lists n Using an index … for ( int i = 0; i < accts. size(); i++ ) { Bank. Account cur. Account = accts. get( i ); System. out. println( … ); } n Using an “enhanced for” … for ( Bank. Account b : accts ) { System. out. println( b. get. Balance() ); Simpler than a regular for loop. All you have to specify } is the object (Bank. Account) and the Array. List (accts).
Exercises n Modify the Bank class, add a create. Account() method that adds another Bank. Account object for the Bank to manage. n n First, do this using an array (accounts). Then, convert Bank from arrays to Array. Lists.
- Slides: 41