January 13th, 2014
ArrayLists and Generic Classes
The ArrayList class is a generic class: ArrayList
/** A bank account has a balance that can be changed by deposits and withdrawals. */ public class BankAccount { /** Constructs a bank account with a zero balance @param anAccountNumber the account number for this account */ public BankAccount(int anAccountNumber) { accountNumber = anAccountNumber; balance = 0; } /** Constructs a bank account with a given balance @param anAccountNumber the account number for this account @param initialBalance the initial balance */ public BankAccount(int anAccountNumber, double initialBalance) { accountNumber = anAccountNumber; balance = initialBalance; } /** Gets the account number of this bank account. @return the account number */ public int getAccountNumber() { return accountNumber; } /** Deposits money into the bank account. @param amount the amount to deposit */ public void deposit(double amount) { double newBalance = balance + amount; balance = newBalance; } /** Withdraws money from the bank account. @param amount the amount to withdraw */ public void withdraw(double amount) { double newBalance = balance - amount; balance = newBalance; } /** Gets the current balance of the bank account. @return the current balance */ public double getBalance() { return balance; } private int accountNumber; private double balance; }
A driver class:
import java.util.ArrayList; /** This program tests the ArrayList class. */ public class ArrayListTester { public static void main(String[] args) { ArrayListaccounts = new ArrayList (); accounts.add(new BankAccount(1001)); accounts.add(new BankAccount(1015)); accounts.add(new BankAccount(1729)); accounts.add(1, new BankAccount(1008)); accounts.remove(0); System.out.println("Size: " + accounts.size()); System.out.println("Expected: 3"); BankAccount first = accounts.get(0); System.out.println("First account number: " + first.getAccountNumber()); System.out.println("Expected: 1015"); BankAccount last = accounts.get(accounts.size() - 1); System.out.println("Last account number: " + last.getAccountNumber()); System.out.println("Expected: 1729"); } }
A different implementation:
Note: pay attention to the for-each loops
import java.util.ArrayList; /** This bank contains a collection of bank accounts. */ public class Bank { /** Constructs a bank with no bank accounts. */ public Bank() { accounts = new ArrayList(); } /** Adds an account to this bank. @param a the account to add */ public void addAccount(BankAccount a) { accounts.add(a); } /** Gets the sum of the balances of all accounts in this bank. @return the sum of the balances */ public double getTotalBalance() { double total = 0; for (BankAccount a : accounts) { total = total + a.getBalance(); } return total; } /** Counts the number of bank accounts whose balance is at least a given value. @param atLeast the balance required to count an account @return the number of accounts having least the given balance */ public int count(double atLeast) { int matches = 0; for (BankAccount a : accounts) { if (a.getBalance() >= atLeast) matches++; // Found a match } return matches; } /** Finds a bank account with a given number. @param accountNumber the number to find @return the account with the given number, or null if there is no such account */ public BankAccount find(int accountNumber) { for (BankAccount a : accounts) { if (a.getAccountNumber() == accountNumber) // Found a match return a; } return null; // No match in the entire array list } /** Gets the bank account with the largest balance. @return the account with the largest balance, or null if the bank has no accounts */ public BankAccount getMaximum() { if (accounts.size() == 0) return null; BankAccount largestYet = accounts.get(0); for (int i = 1; i < accounts.size(); i++) { BankAccount a = accounts.get(i); if (a.getBalance() > largestYet.getBalance()) largestYet = a; } return largestYet; } private ArrayList accounts; }
A driver class:
/** This program tests the Bank class. */ public class BankTester { public static void main(String[] args) { Bank firstBankOfJava = new Bank(); firstBankOfJava.addAccount(new BankAccount(1001, 20000)); firstBankOfJava.addAccount(new BankAccount(1015, 10000)); firstBankOfJava.addAccount(new BankAccount(1729, 15000)); double threshold = 15000; int c = firstBankOfJava.count(threshold); System.out.println("Count: " + c); System.out.println("Expected: 2"); int accountNumber = 1015; BankAccount a = firstBankOfJava.find(accountNumber); if (a == null) System.out.println("No matching account"); else System.out.println("Balance of matching account: " + a.getBalance()); System.out.println("Expected: 10000"); BankAccount max = firstBankOfJava.getMaximum(); System.out.println("Account with largest balance: " + max.getAccountNumber()); System.out.println("Expected: 1001"); } }
Classwork:
Modify the Purse class to be a generic class and to use a for-each loop.
Homework:
Implement the following methods in the Purse class:
/** Counts the number of coins in the purse @return the number of coins */ public int count() { } /** Tests if the purse has a coin that matches a given coin. @param aCoin the coin to match @return true if there is a coin equal to aCoin */ public boolean find(Coin aCoin) { } /** Counts the number of coins in the purse that match a given coin. @param aCoin the coin to match @return the number of coins equal to aCoin */ public int count(Coin aCoin) { } /** Finds the coin with the largest value. (Precondition: The purse is not empty) @return a coin with maximum value in this purse */ Coin getMaximum() { }
***********************************************************************************************
The following code and concepts are for more in-depth knowledge of generics and type parameters.
A Generic Version of the Box Class
/** * Generic version of the Box class. * @paramthe type of the value being boxed */ public class Box { // T stands for "Type" private T t; public void set(T t) { this.t = t; } public T get() { return t; } }
Invoking and Instantiating a Generic Type
To reference the generic Box class from within your code, you must perform a generic type invocation, which replaces T with some concrete value, such as Integer:
Box
You can think of a generic type invocation as being similar to an ordinary method invocation, but instead of passing an argument to a method, you are passing a type argument — Integer in this case — to the Box class itself.
Like any other variable declaration, this code does not actually create a new Box object. It simply declares that integerBox will hold a reference to a “Box of Integer”, which is how Box
An invocation of a generic type is generally known as a parameterized type.
To instantiate this class, use the new keyword, as usual, but place
Box
The most commonly used type parameter names are:
E – Element (used extensively by the Java Collections Framework)
K – Key
N – Number
T – Type
V – Value
S,U,V etc. – 2nd, 3rd, 4th types