Building Java Programs: Implementing A Collection Class: Arrayintlist
Building Java Programs: Implementing A Collection Class: Arrayintlist
Chapter 15
Implementing a Collection Class:
ArrayIntList
– When run with this file, your program's output would be:
3
100
-32053278
932085
17
2
Solution using arrays
int[] nums = new int[100]; // make a really big array
int size = 0;
index 0 1 2 3 4 5 6 ... 98 99
value 17 932085 - 100 3 0 0 ... 0 0
32053278
size 5
3
Unfilled arrays
int[] nums = new int[100];
int size = 0;
index 0 1 2 3 4 5 6 ... 98 99
value 17 932085 - 100 3 0 0 ... 0 0
32053278
size 5
4
Other possible operations
public static void add(int[] list, int size, int value, int index)
public static void remove(int[] list, int size, int index)
public static void find(int[] list, int size, int value)
public static void print(int[] list, int size)
...
5
Exercise
• Let's write a class that implements a list using an int[]
– We'll call it ArrayIntList
– behavior:
• add(value), add(index, value)
• get(index), set(index, value)
• size()
• remove(index)
• indexOf(value)
• toString()
...
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
– list.add(42);
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 42 0 0 0
size 7
7
Implementing add, cont.
• To add to end of list, just store element and increase size:
public void add(int value) {
list[size] = value;
size++;
}
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
– list.add(42);
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 42 0 0 0
size 7
8
Implementing add (2)
• How do we add to the middle or end of the list?
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 42 7 5 12 0 0 0
size 7
9
Implementing add (2) cont.
• Adding to the middle or front is hard (see book ch 7.3)
– must shift nearby elements to make room for the new value
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 42 7 5 12 0 0 0
size 7
– Note: The order in which you traverse the array matters!
10
Implementing add (2) code
public void add(int index, int value) {
for (int i = size; i > index; i--) {
list[i] = list[i - 1];
}
list[index] = value;
}
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
– list.add(3, 42);
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 42 7 5 12 0 0 0
size 7
11
Other methods
• Let's implement the following methods next:
– size
– get
– set
– toString
12
Implementing remove
• How can we remove an element from the list?
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
– list.remove(2);
index 0 1 2 //
3 delete
4 5 96 from
7 index
8 9 2
value 3 8 7 5 12 0 0 0 0 0
size 5
13
Implementing remove, cont.
• Again, we need to shift elements in the array
– this time, it's a left-shift
– in what order should we process the elements?
– what indexes should we process?
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
14
Implementing remove code
public void remove(int index) {
for (int i = index; i < size; i++) {
list[i] = list[i + 1];
}
size--;
list[size] = 0; // optional (why?)
}
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 0 0 0 0
size 6
– list.remove(2);
index 0 1 2 //
3 delete
4 5 96 from
7 index
8 9 2
value 3 8 7 5 12 0 0 0 0 0
size 5
15
Running out of space
• What should we do if the client adds more than 10 elements?
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 12 4 8 1 6
size 10
index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
value 3 8 9 7 5 12 4 8 1 6 15 0 0 0 0 0 0 0 0 0
size 11
16
Convenience methods
• Implement the following methods:
– indexOf - returns the first index an element is found, or -1 if not
– isEmpty - returns true if list has no elements
– contains - returns true if the list contains the given int value
if (myList.size() == 0) { if (myList.isEmpty()) {
17
More ArrayIntList
• Let's add some new features to our ArrayIntList class:
1. A method that allows client programs to print a list's elements
2. A constructor that accepts an initial capacity
(By writing these we will recall some features of objects in Java.)
18
The toString method
• Tells Java how to convert an object into a String
ArrayIntList list = new ArrayIntList();
System.out.println("list is " + list);
// ("list is " + list.toString());
• Syntax:
public String toString() {
code that returns a suitable String;
}
20
Multiple constructors
• existing constructor:
public ArrayIntList() {
elementData = new int[10];
size = 0;
}
21
this keyword
• this : A reference to the implicit parameter
(the object on which a method/constructor is called)
• Syntax:
– To refer to a field: this.field
– To call a method:
this.method(parameters);
– To call a constructor this(parameters);
from another constructor:
22
Revised constructors
public ArrayIntList() {
this(10); // calls (int) constructor
}
23
Size vs. capacity
• What happens if the client tries to access an element that is
past the size but within the capacity (bounds) of the array?
– Example: list.get(7); on a list of size 5 (capacity 10)
index 0 1 2 3 4 5 6 7 8 9
value 3 8 9 7 5 0 0 0 0 0
size 5
24
Preconditions
• precondition: Something your method assumes is true
at the start of its execution.
– Often documented as a comment on the method's header:
26
Throwing exceptions (4.5)
throw new ExceptionType();
throw new ExceptionType("message");
27
Exception example
public void get(int index) {
if (index < 0 || index >= size) {
throw new ArrayIndexOutOfBoundsException(index);
}
return elementData[index];
}
28
Postconditions
• postcondition: Something your method promises will be true
at the end of its execution.
– Often documented as a comment on the method's header:
30
Tips for testing
• You cannot test every possible input, parameter value, etc.
– Even a single (int) method has 2^32 different possible values!
– So you must think of a limited set of tests likely to expose bugs.
• the test shouldn't just call methods and print results; it should:
– call the method(s)
– compare their results to a known correct expected value
– if they are the same, report that the test "passed"
– if they differ, report that the test "failed" along with the values
34
Class constants
public static final type name = value;
36
A private method
private type name(type name, ..., type name) {
statement(s);
}
// client code
ArrayIntList list = new ArrayIntList();
...
list.print();
38
The toString method
• Tells Java how to convert an object into a String
ArrayIntList list = new ArrayIntList();
System.out.println("list is " + list);
• Syntax:
public String toString() {
code that returns a suitable String;
}
40
Exercise
• Write a class called StutterIntList.
– Its constructor accepts an integer stretch parameter.
– Every time an integer is added, the list will actually add stretch
number of copies of that integer.
• Example usage:
StutterIntList list = new StutterIntList(3);
list.add(7); // [7, 7, 7]
list.add(-1); // [7, 7, 7, -1, -1, -1]
list.add(2, 5); // [7, 7, 5, 5, 5, 7, -1, -1, -1]
list.remove(4); // [7, 7, 5, 5, 7, -1, -1, -1]
System.out.println(list.getStretch()); // 3
41
Inheritance
• inheritance: Forming new classes based on existing ones.
– a way to share/reuse code between two or more classes
– superclass: Parent class being extended.
– subclass: Child class that inherits behavior from superclass.
• gets a copy of every field and method from superclass
42
An Employee class
public class Employee {
...
public int getHours() {
return 40; // works 40 hours / week
}
public double getSalary() {
return 40000.0; // $40,000.00 / year
}
public int getVacationDays() {
return 10; // 2 weeks' paid vacation
}
public String getVacationForm() {
return "yellow"; // use the yellow form
}
}
– Example:
44
Overriding methods
• override: To replace a superclass's method by writing a new
version of that method in a subclass.
– No special syntax is required to override a method.
Just write a new version of it in the subclass.
45
super keyword
• Subclasses can call overridden methods with super
super.method(parameters)
– Example:
public class Lawyer extends Employee {
// give Lawyers a $5K raise (better)
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary + 5000.00;
}
}
– This version makes sure that Lawyers always make $5K more
than Employees, even if the Employee's salary changes.
46
Calling super constructor
super(parameters);
– Example:
public class Lawyer extends Employee {
public Lawyer(String name) {
super(name); // calls Employee constructor
}
...
}
49
Protected fields/methods
protected type name; // field
– Problem:
• We should be able to treat both lists the same way in client code.
51
Recall: ADT interfaces (11.1)
– Problem:
• They can store only int elements, not any type of value.
54
Type Parameters (Generics)
ArrayList<Type> name = new ArrayList<Type>();
55
Implementing generics
// a parameterized (generic) class
public class name<Type> {
...
}
– By putting the Type in < >, you are demanding that any client that
constructs your object must supply a type parameter.
• You can require multiple type parameters separated by commas.
– The rest of your class's code can refer to that type by name.
57
Generics/arrays, fixed
public class Foo<T> {
private T myField; // ok
58
Comparing generic objects
public class ArrayList<E> {
...
public int indexOf(E value) {
for (int i = 0; i < size; i++) {
// if (elementData[i] == value) {
if (elementData[i].equals(value)) {
return i;
}
}
return -1;
}
}
...
}
– For a generic linked list, the node class must also accept the type
parameter E
60
Generic interface (15.3, 16.5)
61