67
Chapter 23 Organizing list implementations

Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Embed Size (px)

Citation preview

Page 1: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Chapter 23Organizing list implementations

Page 2: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

This chapter discusses

The notion of an iterator. The standard Java library interface

Collection, and some of its related classes.

Page 3: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

A library structure

We have yet to discuss how all the lists that we have implemented are related.

We could organize them like this:

Page 4: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

With this approach we encounter problems when we try to extend the base class for other purposes, such as adding new functionality.

This approach causes class explosion as each circumstance must be implemented in each subclass.

A library structure (cont.)

Page 5: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

A library structure (cont.) The problem is that the class List is a

participant in two distinct hierarchies: an implementation hierarchy and a concrete application hierarchy.

Solution: Use composition rather than extension to handle different implementation strategies.

Page 6: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

A library structure (cont.) Build a separate implementation

hierarchy. Provide each list with an implementation

as a component. This kind of structure is called a bridge.

Page 7: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Implementing List with a bridgepublic abstract class List implements

Cloneable {…public Object get (int i) { return imp.get(i);}…

}

public interface ListImplementation extends Cloneable {…Object get (int i);…

}

Page 8: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Implementing List with a bridge (cont.) The ListImplementation subclasses

are now concrete classes. Each concrete ListImplementation

subclass must provide an appropriate definition of the method get.

class BoundedList implements ListImplementation {…public Object get (int i) { return elements[i];}…

}

Page 9: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Specifying the implementation A ListImplementation is created when a

List is created. We make the client responsible for

determining which implementation to use when creating the List.

This means that deciding which implementation to use for a particular List is not done until run-time.

Page 10: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and
Page 11: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and
Page 12: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and
Page 13: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators

Many of the methods used with List are linear. e.g. indexOf, remove.

The problems of examining each element of a container and of obtaining a “handle” on a particular container element are very general.

An iterator is an object associated with a particular container that provides a means of sequentially accessing each element in the container.

Page 14: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators (cont.)public interface Iterator extends Cloneable

Iterator for accessing and traversing elements of a container.

public void reset ()Initialize this Iterator to reference the first item.

public void advance ()Advance this Iterator to the next item.

require:

!this.done()

Page 15: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators (cont.)public boolean done ()

No more items to traverse in the container.

public Object get ()Container item this Iterator currently references.

require:

!this.done()

public boolean equals (Object obj)The specified Object is an Iterator of the same class as this, and references the same relative item of the same container.

Page 16: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators (cont.)

Assuming c is a container of some sort and i an iterator associated with it, we can access each item in the container as follows:

i.reset();

while (!i.done()) {

do something with i.get(i);

i.advance();

}

Page 17: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators (cont.) An int variable used to index a list is a

simple form of iterator. It is reset by assigning a value of 0, and

advanced by incrementing. The iterator is done when it equals the length

of the list. For two Iterators to be equal, they must

reference the same “relative item” of the same container.

Even if index 3 and 5 are referencing the same object, an Iterator that references the item with index 3 would not be equal to an Iterator that references the item with index 5.

Page 18: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator classes

If an interface is to traverse a container efficiently, it must be linked closely to the container implementation.

Therefore we create classes for each type of container.

Page 19: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

ListIterator

ListIterator implements an Iterator for arrays.

When a ListIterator is created, it is given a reference to the ListImplementation it will traverse.

The “current element” referenced by the Iterator is represented simply as an integer index.

Page 20: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and
Page 21: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and
Page 22: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

LinkedListIterator

In a LinkedList, it is preferable to keep a reference to a Node, which can be advanced efficiently to reference the next Node in the list.

Iterator must have access to the implementation structure of the LinkedList.

A LinkedListIterator keeps a reference to the Node containing the current item.

Page 23: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and
Page 24: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and
Page 25: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Creating an Iterator

Since an Iterator is intimately bound to the List it is traversing, we add functionality for creating an Iterator to the class List.

List forwards the responsibility to its ListImplementation.

public abstract class List implements Cloneable {…/** * Create a new Iterator for this List. */public Iterator iterator () { return new imp.iterator();}…

}

Page 26: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Creating an Iterator (cont.) ListImplementation defines a factory

method that produces the appropriate kind of Iterator.

interface ListImplementation extends Cloneable {…/** * Create a new Iterator for this List. */public Iterator iterator ();…

}

Page 27: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Creating an Iterator (cont.) Concrete implementation classes

implement the factory method to produce an appropriate iterator.

class LinkedList extends ListImplementation {…/** * Create a new Iterator for this List. */public Iterator iterator (){ return new LinkedListIterator(this);}…

}

Page 28: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Creating an Iterator (cont.)

Page 29: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Creating an Iterator (cont.)

Page 30: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Creating an Iterator (cont.)

Page 31: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

List methods with iterators as arguments

We overload the List methods that take index arguments with methods taking iterators as arguments.

Page 32: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

List methods with iterators as arguments (cont.)public Object get (Iterator i)

The element referenced by the specified Iterator.require: this.traversedBy(i) !i.done()

public Iterator iteratorAt (Object obj)An Iterator referencing the first occurrence of the specified element in this List; Iterator is done if this List does not contain the specified element.require: obj != nullensure: if obj equals no element of this List then

iteratorAt(obj).done() else

obj.equals(iteratorAt(obj).get()), and iteratorAt(obj) references the first position in a tarversal for which this is true.

Page 33: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

List methods with iterators as arguments (cont.)public void add (Iterator i, Object obj)

Insert the specified Object at the specified position.require: this.traversedBy(i) !i.done() obj != nullensure: this.size() == old.size() + 1 i.get() == obj (i.advance(); i.get()) == old.i.get()

public void remove (Iterator i)Remove the element at the specified position.require: this.traversedBy(i) !i.done()ensure: this.size() == old.size() - 1 i.get() == (old.i.advance(); old.i.get())

Page 34: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

List methods with iterators as arguments (cont.)public void set (Iterator i, Object obj)

Replace the element at the specified position with the specified Object.require: this.traversedBy(i) !i.done()

public boolean traversedBy (Iterator i)This List is traversed by the specified Iterator.

Page 35: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

List methods with iterators as arguments (cont.) The final postconditions for add and remove indicate a sequene of method calls. The add postcondition (i.advance(); i.get()) == old.i.get() indicates that advancing the iterator followed by a get gives the same element get would have returned before the add.

The remove postcondition i.get() == (old.i.advance(); old.i.get()) indicates that the element referenced by the iterator after the remove is the one following the element that was removed.

Page 36: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

List methods with iterators as arguments (cont.) The implementation of these methods is

straightforward.

public Object get (Iterator i) {

Require.condition(this.traversedBy(i));

return i.get();

}

Most other operations are forwarded to the ListImplementation.

public void remove (Iterator i) {

Require.condition(this.traversedBy(i));

imp.remove(i);

}

Page 37: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Improving LinkedListIterator We defined LinkedListIterator that

referenced the “current” node of a LinkedList.

Page 38: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Improving LinkedListIterator (cont.) This works fine for get and set, but when

we try to implement remove and add, we notice that we need a reference to the Node preceding the current Node.

There are several solutions: keep a pair of references in the Iterator one to the current Node and one to the preceding Node.

We could also simply keep a reference to the Node preceding the current one.

Boundary cases are simplified if LinkedList has a header.

Page 39: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator extensions

We define Iterator extensions that capture the notion of a circular list, and that permit forward and backward traversal of a list.

We can ensure that an Iterator created by a DoublyLinkedList implements the interface CircularIterator. Now the iterator can be moved backward

of forward in a circular fashion.

Page 40: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator extensions (cont.)public interface WrappingIterator extends

IteratorAn Iterator that returns to the beginning of the enumeration when advanced past the last element of the container. done is true if the Iterator s referencing the first item of the enumeration, having been advanced from the last item, or if the container is empty.

public void advanced ()Advance this Iterator to the next item. Advance to the first item if this Iterator is currently referencing the last item in the enumeration.

require:

The container this Iterator is referencing

is not empty.

Page 41: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator extensions (cont.)public boolean done ()

This Iterator currently references the first item of the enumeration having been advanced from the last, or the container is empty.

public Object get ()Container item this Iterator currently references.

require:

The container this Iterator is referencing

is not empty.

Page 42: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator extensions (cont.)public interface BiDirectionalIterator

extends IteratorAn Iterator that can move to previous as well as next item. offRight is true if the Iterator has been advanced past the last element, or if the container is empty. offLeft is true if the Iterator has been backed up past the first element, or if the container is empty.

public boolean done ()This Iterator has been advanced past the last element, or the container is empty. Equivalent to offRight.

Page 43: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator extensions (cont.)public boolean offRight ()

This Iterator has been advanced past the last element, or the container is empty. Equivalent to done.

public boolean offLeft ()This Iterator has been backed up past the first element, or the container is empty.

public void backup ()Move this Iterator back to the previous element.

Page 44: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator extensions (cont.)public interface CircularIterator extends

WrappingIterator, BiDirectionalIteratorAn Iterator can move to next or previous item in the container, and wraps at the ends of the enumeration. That is, moves to the first element when advanced past the last element, and moves to the last element when backed up from the first element.If the container is not empty, the Iterator references the first element of the enumeration when offRight (done) is true.If the container is not empty, the Iterator references the last element of the enumeration when offLeft is true.

public void advance ()Advance this Iterator to the next item. Advance to the first item if this Iterator is currently referencing the last item in the enumeration.require: The container this Iterator is referencing is not empty.

Page 45: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator extensions (cont.)public void backup ()

Move this Iterator back to the previous item. Move to the last item if this Iterator is currently referencing the first item in the enumeration.

require:

The container this Iterator is referencing

is not empty.

Page 46: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators and List modification More than one Iterator can be traversing

the same list. Suppose an Iterator i is referencing a

particular element of a List list, for instance the element with index 2:

Page 47: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators and List modification (cont.) The specifications promise that if we

delete the element referenced by the Iterator, the Iterator will reference the next element.

Page 48: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators and List modification (cont.) The specifications promise that if

we next do list.add(i, x);

Page 49: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators and List modification (cont.) How does an Iterator behave if the List is

modified by means of another Iterator, or by means of an index?

If we do

list.remove(j); or l.remove(2);

what will the state of i be?

Page 50: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators and List modification (cont.) We could build Iterators that are

Observers of an Observable List. The Iterators register with the List. The List informs all its Iterators whenever

it is modified structurally. Instead, we assume that if a List is

modified by index, all Iterators that reference the List become invalid.

Because, Iterators typically have very local scope and short lifetimes, this does not present serious practical problems.

Page 51: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators and List modification (cont.) We could add methods to the class List

that take several Iterators as arguments.

public void remove (Iterator i1, Iterator i2)Delete all the elements of this List from the element specified by the first Iterator through the element specified by the second, inclusive.

The postconditions describe the state of the Iterators after the method is executed.

Page 52: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Internal or passive Iterators Internal or passive Iterators shift

the responsibility from the client to the iterator.

A client provides an operation and the iterator applies the operation to each element of the container.

When the Iterator is created, it is provided with a List, a condition, and an operation.

Page 53: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Internal or passive Iterators (cont.)public interface Predicate {

public boolean evaluate (Object obj);

}

public interface Operation {

public void execute (Object obj);

}

Page 54: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Internal or passive Iterators (cont.) The internal iterator constructor takes a List,

Predicate, and Operation as arguments. Its single command applies the Operation to all

List elements that satisfy Predicate.public class ListTraverse

Internal iterator that performs a spcified operation on each List element that satisfies a given condition.

public ListTraverser (List list, Predicate p, Operation op)Create a new iterator with the specified List, Predicate, and Operation.

public void traverse ()Apply the Operation to each element of the List that satisfies the Predicate.

Page 55: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Internal or passive Iterators (cont.) An Iterator to print out all students on

StudentList CourseList who have a final average greater than 90.

ListTraverser listA = new ListTraverser (new Predicate () { public boolean evaluate (Object obj) {

return ((Student)obj).finalAve()>90; }},new Operation () { public void execute (Object obj) {

System.out.println(((Student)obj).name());

}},courseList);

Page 56: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Internal or passive Iterators (cont.) The Iterator defines “anonymous”

classes. To perform the iteration, we give the

Iterator the traverse command:

listA.traverse();

Page 57: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Comparing implementations

Page 58: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

The java.util Collection hierarchy The standard Java package java.util

defines the interface Collection. The interface Collection models a rather

generalized container.

public boolean contains (Object o)This collection contains the specified element.

public boolean isEmpty ()This collection contains no elements.

public int size ()The number of elements in this collection.

public java.util.Iterator iterator()An iterator over the elements in this collection.

Page 59: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

The java.util Collection hierarchy (cont.) Operations to add and remove elements

are “optional.” Example:

public boolean add (Object o) throws UnsupportedOperationException, ClassCastException, IllegalArgument Exception {…}

Page 60: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

The java.util Collection hierarchy (cont.) If the operation add is not supported by

the implementing class, an UnsupportedOperationException is thrown.

If the class of the argument prevents it from being added to the Collection, a ClassCastException is thrown.

If any aspect of of the object other than its class prevents it from being added to the Collection, an IllegalArgument is thrown.

Page 61: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

List

List is an interface that extends Collection.

It includes:public Object get (int index)

The element at the specified position in this List.

Page 62: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Hierarchy

Corresponding to the interfaces Collection, List, and Set are abstract classes AbstractCollection, AbstractList, and AbstractSet.

Array-based list implementations such as java.util.Vector extend AbstractList directly.

Linked implementations, such as java.util.LinkedList, extend the abstract class AbstractSequentialList, which extends AbstractList.

Page 63: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Hierarchy (cont.)

Page 64: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterators The java.util interface Iterator specifies

three methods:

public boolean hasNext()The iteration has more elements.next

public Object next () throws NoSuchElementExceptionThe next element in the interation. Throws NoSuchElementException if hasNext() is false.

public void remove () throws UnsupportedOperationException, IllegalStateExceptionRemoves from the underlying collection the last element returned by the iterator (optional operation). This method can be called only once per call to next.

Page 65: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Iterator (cont.)

next is not a proper query since it changes the state of the iterator.

public Object next () {

Object temp = this.get();

this.advance();

return temp;

}

Page 66: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

We’ve covered

Organizing list classes into a coherent library structure.

Separating the List abstraction hierarchy from the implementation hierarchy by use of a bridge.

Method performance. External Iterators. Internal Iterator abstraction. Collection interfaces and abstraction found

in the standard Java Package java.util.

Page 67: Chapter 23 Organizing list implementations. This chapter discusses n The notion of an iterator. n The standard Java library interface Collection, and

Glossary