Top Banner
Chapter 21 Implementing lists: array implementation
50

Chapter 21 Implementing lists: array implementation.

Mar 26, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Chapter 21 Implementing lists: array implementation.

Chapter 21Implementing lists: array implementation

Page 2: Chapter 21 Implementing lists: array implementation.

This chapter discusses

Implementing the class List. Implementations on a primitive

language-provided structure called an array.

Several important relationships between classes used to effect various implementations.

Page 3: Chapter 21 Implementing lists: array implementation.

Arrays array: a structure composed of a contiguous

sequence of variables, all of the same type. Individual variables are identified by index

values or indexes. Index values are integers, (beginning with 0

in Java). Components or elements are the variables

that comprise the array. They are a primitive type (char, int,

boolean, double, etc.) or a reference type (reference to an object).

Page 4: Chapter 21 Implementing lists: array implementation.

Arrays (cont.)

The length of the array is the number of component variables that comprise it.

With length n, the component variables are indexed 0 through n-1.

Page 5: Chapter 21 Implementing lists: array implementation.

Arrays (cont.)

The length of an array is fixed when the array is created.

Since contiguous memory is allocated for the variables, accessing a particular variable in the array requires a constant amount of time independent of the array length.

Page 6: Chapter 21 Implementing lists: array implementation.

Arrays (cont.) Suppose each variable in a particular

array may take up four bytes, and memory is allocated starting at location 100

The address of the variable with index i is 100+4*i.

(starting address)+(variable size)*(element index)

The calculation of the address requires constant time, independent of the index and independent of the size of the array.

Page 7: Chapter 21 Implementing lists: array implementation.

Array objects

Arrays in Java are encapsulated in objects.

Array objects have a public int component length.

The class of an array is determined by the type of its component variables.

The class is written as the component type followed by a pair of brackets. int[]

Student[]

Page 8: Chapter 21 Implementing lists: array implementation.

Defining arraysint[] grades;Student[] cs2125;

int grades[];Student cs2125[];

The variable contains a reference to an array object.

We use a constructor to create the array object.

grades = new int[5];cs2125 = new Student[5];

Page 9: Chapter 21 Implementing lists: array implementation.

Defining arrays (cont.)

Page 10: Chapter 21 Implementing lists: array implementation.

Defining arrays (cont.)

The component variables of the arrays are initialized with standard default values. e.g. 0 for int, null for references.

The length given in the constructor need not (and generally should not) be a literal.

cs2125 = new Student[studentCount];

grades = new int[4*cs2125.length];

Page 11: Chapter 21 Implementing lists: array implementation.

Accessing array components A reference to the array is followed by an

index value in brackets.grades[3] = 100;

grades[4] = grades[3]/2;

cs2125[0] = new Student(…);

cs2125[0].payFees(100);

int i;

for(i = 0; i < grades.length; i=i+1)

grades[i] = 100;

The index value must be an int, non-negative, and less than the length of the array.

Page 12: Chapter 21 Implementing lists: array implementation.

Accessing array components (cont.) If an array is referenced with an

index that is negative or is not less than the array length, an ArrayIndexOutOfBoundsException is thrown.

Page 13: Chapter 21 Implementing lists: array implementation.

BoundedListpublic abstract class BoundedList

A list of objects with a fixed maximum size.

protected BoundedList (int maxSize)Create a new BoundedList with a specified maximum size.require: maxSize >= 0ensure: isEmpty(new BoundedList(n))

Since the class is abstract and an abstract constructor can be invoked only by a subclass, it is declared protected.

Page 14: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.) Component variables:private Object[] elements;

private int size;

elements will hold the components of the array.

size will hold the current length of the list (not the maximum number of elements).

Page 15: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)protected BoundedList (int maxSize){

Require.condition(maxSize >= 0);elements = new Object[maxSize];size = 0;

}public int size() {

return this.size;}public Object get (int i) {

Require.condition(0 <= i && i < size);return element[i];

}public void append (Object obj) {

Require.notNull(obj);Require.condition(size < elements.length);elements[size] = obj;size = size+1;

}

Page 16: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)public void add (int i, Object obj) {

Require.notNull(obj);Require.condition( 0 <= i && i <= size);Require.condition(size < elements.length);int j;for (j = size-1; j >= i; j = j-1) elements[j+1] = element[j];elements[i] = obj;size = size + 1;

}public void remove (int i) {

Require.condition(0 <= i && i < size);int j;for ( j = i; j < size-1; j = j+1) elements[j] = element[j+1];size = size - 1;

}

Page 17: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)public void set (int i, Object obj) {

Require.notNull(obj);Require.condition( 0 <= i && i < size);elements[i] = obj;

}public void clear () {

size = 0;}

Page 18: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)

The methods add (and remove) “shuffle” a portion of the array up or down.

Elements must be moved starting with the last, or else elements will be overwritten.

Page 19: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)

For instance, if we writefor ( j = i; j < size; j= j+1)

elements[j+1] = elements[j];

Page 20: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)

When elements are deleted with clear or remove, there is no need to set array components to null.

These elements are considered “invalid;” it does not matter what they contain.

Page 21: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)public boolean isEmpty () {

return this.size() == 0;}

public int indexOf (Object obj) {int i; int n = this.size();i = 0;while (i <n && !obj.equals(get(i))) i = i+1;if (i == n) return -1;else return i;

}

Page 22: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)public String toString () {

String s = “[”;int n = this.size();if (n > 0) { s = s + this.get(0).toString(); int i; for(i = 1; i < n; i = i+1)

s = s + “, ” +

this.get(i).toString();}s= s + “]”;

}

public int maxSize () {return elements.length;

}

Page 23: Chapter 21 Implementing lists: array implementation.

The method copy

We make a shallow copy of the list. i.e. the original list and the copy reference the same list elements.

Page 24: Chapter 21 Implementing lists: array implementation.

The method copy (cont.)public BoundedList copy() {

int i;

BoundedList theCopy = new

BoundedList(elements.length);

for (i = 0; i < size; i=i+1) {

theCopy.elements[i] = this.elements[i];

theCopy.size = this.size;

return theCopy;

} //This doesn’t work because BoundedList is an abstract class.

Page 25: Chapter 21 Implementing lists: array implementation.

Java Interface Cloneable Object class has a method clone.

protected Object clone ()

throws CloneNotSupportedException

Create a copy of this Object.

This method has these properties

s != s.clone()

s.equals(s.clone());

s.clone() instanceof Student //of course we are implying that ‘s’ is a Student.

Since clone returns an object, it is often necessary to cast the result.

Student s2 = (Student) s.clone();

Page 26: Chapter 21 Implementing lists: array implementation.

Java Interface Cloneable (cont.)public interface Cloneable {}

Any class that supports the method clone should implement this interface. If not, a CloneNotSupportedException is thrown.

The method clone works essentially like this:

if (this instanceof Cloneable) {Object copy = new instance of this class;for each component variable v of this copy.v = this.v;return copy;

elsethrow CloneNotSupportedException;

Page 27: Chapter 21 Implementing lists: array implementation.

Java Interface Cloneable (cont.) Implementing the interface does not

require a class to implement any methods; the class inherits the method clone implemented in the class Object.

Page 28: Chapter 21 Implementing lists: array implementation.

Java Interface Cloneable (cont.) If Java were built with multiple

inheritance, Cloneable would be a class from which other objects could inherit and the method clone would be defined there.

Page 29: Chapter 21 Implementing lists: array implementation.

Java Interface Cloneable (cont.) It simply “turns on” the method clone

inherited from Object.

Page 30: Chapter 21 Implementing lists: array implementation.

BoundedList

public abstract class BoundedList implements Clonable {

public Object clone() {

BoundedList theCopy =

(BoundedList)super.clone();

Page 31: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)

We may want a less shallow copy of the list so that we can manipulate the list and its clone independently.

Page 32: Chapter 21 Implementing lists: array implementation.

BoundedList (cont.)public Object clone() {

try { BoundedList theCopy =

(BoundedList)super.clone(); theCopy.elements =

(Object[])this.elements.clone(); return theCopy;} catch (CloneNotSupportedException e) { return null;}

}

Page 33: Chapter 21 Implementing lists: array implementation.

Implementation

We need to cast the result explicitly to BoundedList or Object[ ] as appropriate.

Java’s scoping rules allow private components of the BoundedList theCopy to be accessed directly in the method.

Since the Object method clone is specified as possibly throwing a CloneNotSupportedException, we must include a try statement and catch it, or include a throws clause in the specifications of the method.

Page 34: Chapter 21 Implementing lists: array implementation.

Implementation (cont.)

In order to have an abstract class that creates a new object, we implement a method like this:

public BoundedList copy () {

return (BoundedList) this.clone();

}

The object created by the call to super.clone() will be of the same run-time class as the object executing the call.

Page 35: Chapter 21 Implementing lists: array implementation.

Abstract Constructor An abstract method can be used like a

constructor for creating objects in a superclass.

Sometimes it is called a factory method. Subclasses implement the method and

determine which actual concrete class to instantiate.

public abstract BoundedList createList (int maxSize)Create a new BoundedList with a specified maximum size.require: maxSize >= 0ensure: isEmpty(createList(n))

Page 36: Chapter 21 Implementing lists: array implementation.

Abstract constructor (cont.)

Page 37: Chapter 21 Implementing lists: array implementation.

Abstract constructor (cont.)public class BoundedStudentList extends

BoundedList {…/** * Create a new BoundedStudent list * require: * maxSize >= 0 * ensure: * isEmpty(createList(n)) * createList(n) instanceof * BoundedStudentList */

public BoundedList createList (int

maxsize) { return new BoundedStudentList

(maxsize);}…

}

Page 38: Chapter 21 Implementing lists: array implementation.

Abstract constructor (cont.)public BoundedList copy() {

int i;BoundedList theCopy = createList( this.element.size);for (i = 0; i < this.size; i=i+1) theCopy.elements[i]=this.elements[i];theCopy.size = this.size;return theCopy;

}

Page 39: Chapter 21 Implementing lists: array implementation.

Advantages of arrays

Elements can be accessed efficiently; get, append, and set all operate in constant time.

Page 40: Chapter 21 Implementing lists: array implementation.

Limitations of arrays

The array is static. The client must have a good idea of the ultimate size of a list when the list is created. Too large means wasted space. Too small causes failure.

Operations remove, add, and indexOf all are linear.

Conclusions Not the best implementation for dynamic

lists. Often a good choice for static lists.

Page 41: Chapter 21 Implementing lists: array implementation.

Dynamic arrays

A bounded list has a maximum size.

A dynamic list has no maximum size.

A static array can be made into a dynamic array by simply creating a bigger array when the original array is full.

Page 42: Chapter 21 Implementing lists: array implementation.

Dynamic listspublic void append (Object obj) {

Require.notNull(obj);if (this.size == elements.length) { // need a bigger array Object[] newArray = new

Object[2*elements.length]; //copy contents of old array to new int i; for(i = 0; i < elements.length; i=i+1)

newArray[i] = elements[i]; elements = newArray;}elements[size] = obj;size = size +1;

}/*append becomes a very expensive operation because there is the possibility of having to copy the entire array into a new array. (linear time) */

Page 43: Chapter 21 Implementing lists: array implementation.

Vector class

Vector class is a container class that encapsulates a “dynamic” use of arrays.

public Vector ();

public Vector (int initialCapacity);

public Vector (int initialCapacity, int capacityIncrement);

New Vector (100,20)

default initialCapacity = 10

default capacityIncrement = 0

capacityIncrement of 0 means it doubles everytime it outgrows capacity.

Page 44: Chapter 21 Implementing lists: array implementation.

Wrapper A class that adds functionality to or

modifies the specification of another class.

A class that provides required functionality but lacks the required interface can be tailored to fit our needs by wrapping the class in a wrapper class.

Vector has all of the functionality and most of the methods of lists.

Page 45: Chapter 21 Implementing lists: array implementation.

Wrapper specifications

public Object elementAt(int index);The element at the given array index.

public int indexOf (Object elem)Index of the given element; -1 if the array does not contain the element.

public int size ()The number of elements in the Vector.

public Object clone()A new copy of the Vector.

public void addElement (Object elem)Add the element to the end of the Vector; size is increased, and capacity is incremented if necessary.

public void insertElementAt (Object obj, int index)Add the given element at the given array index, shifting elements up as necessary.

Page 46: Chapter 21 Implementing lists: array implementation.

Wrapper specifications (cont.)public void removeElementAt (int index)

Remove the element at the given index, and shift higher indexed elements down.

public void setElementAt (Object obj, int index)Replace the element at the specified array index with the Objectt provided.

public String toString()A string representation of this Vector, containing the String representation of each element.

public void removeAllElements()Removes all the components from this Vector and sets its size to zero.

The time complexity of the methods is the same as with BoundedList.

Page 47: Chapter 21 Implementing lists: array implementation.
Page 48: Chapter 21 Implementing lists: array implementation.
Page 49: Chapter 21 Implementing lists: array implementation.

We’ve covered

Java’s array classes Object arrays used to implement a

version of the class List Cloning arrays Solving the fixed array limitation

Vectors Dynamic arrays Wrappers

Time complexities.

Page 50: Chapter 21 Implementing lists: array implementation.

Glossary