You are on page 1of 20

# Introduction to Computation and Problem Solving

Prof. Steven R. Lerman and Dr. V. Judson Harward

The Java Collection Classes
• The java.util package contains implementations of many data structures that we are also going to discuss and implement in a simpler way in class. • You are welcome to use the standard Java implementations in problem sets. They are more elaborate and abstract than the implementations we will develop. • Learning how to implement a few data structures makes you more sophisticated in how you use all data structures. • We will cover the Java implementations in a later lecture.
2

1

Goals
• We will examine and build a new kind of data structure (a Linked List) using linking rather than arrays. • The most important theme, however, is that implementation affects how useful a data structure is as much as its interface (set of methods).

3

Lists as an Abstract Data Type A list is a collection of elements that has a particular order.
– It can have arbitrary length. – You should be able to insert or delete an element anywhere. – You should be able to go through the list in order an element at a time.

4

2

public void addLast( E e ). public boolean contains( E e ). } 5 Lists and Ordinal Position • There are certain obvious things we would like to do with lists that we can't do using only this interface. public boolean remove( E e ). public void clear(). Two examples: – How would you access the elements of the list if you did not know them in advance? – How would you insert an item into the list at any other position than the beginning and the end? • One approach is to number or index the positions in the list. 6 3 .A List Interface public interface List<E> { public boolean isEmpty(). public int size(). public void addFirst( E e ). public E removeFirst() throws NoSuchElementException.

it can change every time an item is added to or deleted from the list. . – public void add( E e. • When we use large lists like a telephone directory in everyday life. – Since the index depends on ordinal position. . – public E remove( int n ) throws IndexOutOfBoundsException. • The following code block will traverse an indexed list. 8 4 . • The idea of using an index to access list members can lead to problems. 2 • Lists implemented using arrays (e. accessing an indexed element is slow. however. Java’s ArrayList) often provide such methods because they are easy to implement.g.. – If the list is not implemented on top of an indexed data structure like an array.size().get( i ). i < myList. myList: for ( int i = 0. we don't consider the index of an entry.Indexed Lists • We could then add three methods – public E get( int n ) throws IndexOutOfBoundsException. only its relative position. int n ) throws IndexOutOfBoundsException. } 7 Indexed Lists. i++ ) { E e = myList. .

• It has methods to return the collection's members one at a time. public void remove() throws IllegalStateException. public E next() throws NoSuchElementException. • Iterators can also implement methods that allow the collection to be modified relative to the current position of the iterator. public void set( E e ) throws IllegalStateException } 10 5 .Iterators • An iterator is a helper class designed to be used with a List or other collection class. 9 SListIterator Interface public interface SListIterator<E> { public boolean hasNext(). Think of it as a movable bookmark. public void add( E e ).

Before the first call to next(). • Can you have 2 iterators over the same List? 12 6 . After a call to add(). The Java ListIterator allows you to go forwards and backwards. next(). • add() will insert a new element after the current element and before the element that would be returned by the following call to next(). there is no current element. • The first call to next() returns the first element of the list.Iterator Methods • The type of iterator we present here returns a new element and advances to the next with the same operation. • The most recent element returned by next() is the current element. • We do this by adding a method to our List interface: public SListIterator slistIterator(). 11 Iterator and its Underlying List • An iterator is an object based on an underlying collection so we need a way to create an iterator for a collection. There is no way to go back using this interface. A call to next() will return the element after the inserted one. • remove() will delete the current element from the underlying collection. set() will change it. the inserted element becomes the new current.

. . . . . while ( iter.next(). .slistIterator(). . .Using an Iterator List<String> myList = new SLinkedList<String>(). .hasNext() ) { String s = iter. } 13 An SListIterator in Action New Iterator green red purple orange current undefined After 1st call to next() green red purple orange current is green After adding black green black red purple orange current is black After 2nd call to next() green black red purple orange current is red 14 7 . SListIterator<String> iter = myList.

• For this reason.An SListIterator in Action.g.. 2 After calling remove() green black purple orange current is undefined After 3rd call to next() green black purple orange current is purple 15 List Implementation Stategies • There are many ways to implement a list. lists frequently use a linked implementation (e. There is a similar problem with deletion. Java’s LinkedList) 16 8 . • In array-based implementations like the Java Arraylist inserting an element at any place except the end of the list is very expensive because all the elements from the point of insertion until the end must be moved back to make room for the new entry.

17 Singly Linked List Diagram List first last Link 1 Link 2 .. • The last link in the list points to nothing. but it also points to the next item in the list as one freight car is coupled to the next. • In a singly linked list.Singly Linked Lists • Linked lists are like freight trains. the link not only contains the listed item. • Each item to be put on the list is contained in an instance of a new type of object called the link corresponding to a freight car. Link n null Item 1 Item 2 Item n 18 9 ..

. private int length = 0. next = n. } SLink( E e ) { this( e. SLink<E> n ) { item = e. . private SLink<E> last = null. • last and length could be found by traversing the list. private SLink<E> first = null. } } . but having these members and keeping them up to date makes the calls size() and append() much faster.The Link Inner Class public class SLinkedList<E> implements List<E> { private static class SLink<E> { E item. null ). SLink( E e. SLink<E> next. 21 The SLinkedList Data Members • Only first is necessary. 22 11 .

equals( b ). } 23 Beware the Special Case • The tricky part about implementing a linked list is not implementing the normal case for each of the methods. What does it means to find it? • Must the list contain a reference to the identical object (==)? Or is it sufficient that the list contain a reference to an object that is equal but possibly distinct? static private <E> boolean objectEquals( E a. for instance. – a list with only one or two elements. else return a.== vs the Object equals method • contains( E e ) and remove( E e ) must search for E e in the list. removing an object from the middle of the list. • What's tricky is making sure that your methods will work in the exceptional and boundary cases. – on the last element of a list. you should think through whether the implementation will work on – an empty list. – on the first element of a list. E b ) { if ( a == null ) return ( b == null ). • For each method. 24 12 .

} else { first = new SLink<E>( e. } 28 14 . special case before List first last after List first last null Link 1 null Item 1 27 addFirst(Object o) public void addFirst(E e) { if ( first == null ) // if the list is empty { first = last = new SLink<E>( e ). } length++. first ).addFirst().

Link n null Item 1 Item 2 Item n 29 removeFirst(). Link n null Item 1 Item 2 Item n 30 15 .. after List first last Link 1 Link 2 . before List first last Link 1 Link 2 ...removeFirst()..

removeFirst(). length--. } } 32 16 .item.next. else { SLink<E> t = first. // if list had 1 element and is now empty if ( first == null ) last = null. special case before List first last after List first last Link 1 null Link 1 null Item 1 Item 1 31 removeFirst() public E removeFirst() throws NoSuchElementException { if ( first == null ) // if list is empty throw new NoSuchElementException(). first = first. return t.

.next(). } 34 17 . . } } return false. } public class SLinkedListIterator implements SListIterator<E> { . . } } 33 contains() public boolean contains(E e) { SListIterator<E> iter = new SLinkedListIterator().SListIterator as Inner Class public class SLinkedList<E> { . while ( iter. public SListIterator<E> slistIterator() { return new SLinkedListIterator(). .hasNext() ) { if ( objectEquals( iter. e )) { return true.