computer science 209 software development iterators

22
Computer Science 209 Software Development Iterators

Upload: brandon-porter

Post on 16-Dec-2015

226 views

Category:

Documents


2 download

TRANSCRIPT

Computer Science 209

Software Development

Iterators

Implementing Equals

public boolean equals(Object other){ if (this == other) return true; if (! (other instanceof LinkedStack)) return false; LinkedStack<E> otherStack = (LinkedStack<E>)other; if (this.size() != otherStack.size()) return false; return this.containsAll(otherStack) && otherStack.containsAll(this);}

Can result in quadratic running time

What if the two stacks contain the same elements, but they are not in the same order?

Implementing Equals

public boolean equals(Object other){ if (this == other) return true; if (! (other instanceof LinkedStack)) return false; LinkedStack<E> otherStack = (LinkedStack<E>)other; if (this.size() != otherStack.size()) return false; for (int i = 0; i < this.size(); i++) if (! this.list.get(i).equals(otherStack.list.get(i))) return false; return true;}

get runs in constant time for ArrayList but in linear time for LinkedStack

Results in quadratic running time for LinkedStack.equals

Implementing Equals

public boolean equals(Object other){ if (this == other) return true; if (! (other instanceof LinkedStack)) return false; LinkedStack<E> otherStack = (LinkedStack<E>)other; if (this.size() != otherStack.size()) return false; Iterator<E> otherIter = otherStack.iterator(); for (E thisElement : this) if (! thisElement.equals(otherIter.next())) return false; return true;}

next runs in constant time for any collection’s iterator

Results in linear running time for any equals

The Iterator Interface

public interface Iterator<E>{

public boolean hasNext() public E next() public void remove()}

remove deletes the object most recently accessed with next

remove must be included in the implementing class, but need not be supported (can throw an UnsupportedOperationException)

Using an Iterator

// add a bunch of objects to col

Iterator<SomeType> iter = col.iterator();

Every collection class that supports an iterator must provide aniterator method.

This method returns an instance of a class that implements the Iterator interface

anIterator aCollectionA sequence of elements

// add a bunch of objects to col

Iterator<SomeType> iter = col.iterator();

while (iter.hasNext()){ SomeType obj = iter.next(); System.out.println(obj);}

Using an Iterator

D D Dcollection

iterator

// add a bunch of objects to col

Iterator<SomeType> iter = col.iterator();

while (iter.hasNext()){ SomeType obj = iter.next(); System.out.println(obj);}

Using an Iterator

D D Dcollection

iterator

// add a bunch of objects to col

Iterator<SomeType> iter = col.iterator();

while (iter.hasNext()){ SomeType obj = iter.next(); System.out.println(obj);}

Using an Iterator

D D Dcollection

iterator

// add a bunch of objects to col

Iterator<SomeType> iter = col.iterator();

while (iter.hasNext()){ SomeType obj = iter.next(); System.out.println(obj);}

Using an Iterator

D D Dcollection

iterator

// add a bunch of objects to col

for (SomeType obj : col) System.out.println(obj);

Iterable and the for-each Loop

D D Dcollection

iterator

If col implements the Iterable interface, the client can use a for-each loop instead

Use in AbstractCollectionabstract public class AbstractCollection<E> implements Collection<E>{ public void clear(){ Iterator<E> iter = this.iterator(); while (iter.hasNext()){ iter.next(); iter.remove(); } }

public boolean remove(Object o){ Iterator<E> iter = this.iterator(); while (iter.hasNext()) if (iter.next().equals(o)){ iter.remove(); return true; } return false; }

public boolean hasNext()

public E next()

Preconditions on Methods

hasNext has no preconditions

next has two preconditions:• hasNext returns true• the underlying collection has not been modified by one of that collection’s mutators during the lifetime of that iterator

// Add a bunch of objects to col

Iterator<SomeType> iter = col.iterator();

while (iter.hasNext()){ SomeType obj = iter.next(); <blah blah blah>}

SomeType obj = iter.next(); // This should cause an exception

Error: Run Out of Elements

// Add a bunch of objects to col

Iterator<SomeType> iter = col.iterator();

while (iter.hasNext()){ col.removeLast(); SomeType obj = iter.next(); // This should cause an exception}

Error: Inconsistent Data

Using mutators in conjunction with iterators is a bad practice

An Iterator Implementation

The iterator method is in the Iterable interface

public interface TrueStack<E> extends Collection<E>{

public E pop();

public void push(E newElement);

public E peek();}

<<Interface>>Collection

<<Interface>>Iterable

<<Interface>>TrueStack

public class ArrayStack<E> extends AbstractCollection<E> implements TrueStack<E>{

private List<E> list;

// Code for constructors, push, pop, peek, size, and add

public Iterator<E> iterator(){ return list.iterator(); }

An Iterator Implementation

Problem: a list’s iterator supports the remove method

Another Design Strategy

• By using the list’s iterator, we expose it to the client (Law of Demeter?)

• Let’s use it, but wrap our own iterator object around it

• That allows us to control what’s supported and what’s not

public class ArrayStack<E> extends AbstractCollection<E> implements TrueStack<E>{

private List<E> list;

// Code for push, pop, peek, size, and add

// Code for the iterator method

// Code for the class that implements the Iterator // interface}

An Iterator Implementation

Define the iterator class as a private inner class.

public Iterator<E> iterator(){ return new StackIterator<E>(this.iterator());}

private class StackIterator<E> implements Iterator<E>{

public boolean hasNext(){ return false; }

public E next(){ return null; }

public void remove(){ }

}

The Implementing Class

NestedwithinArrayStack

public Iterator<E> iterator(){ return new StackIterator<E>(list.iterator());}

private class StackIterator<E> implements Iterator<E>{

private Iterator<E> iter;

private StackIterator(Iterator<E> iter){ this.iter = iter; }

// Other methods }

The Implementing Class

NestedwithinArrayStack

private class StackIterator<E> implements Iterator<E>{

private Iterator<E> iter;

public boolean hasNext(){ return iter.hasNext(); }

public E next(){ return iter.next(); }

public void remove(){ throw new UnsupportedOperationException( "remove not supported by Stack"); }}

Other Methods