Title: Computer Science 187
1Computer Science 187
Introduction to Programming with Data Structures
Lecture 8 Lists, Iterators, and Doubly Linked
Lists
2Computer Science 187
Introduction to Programming with Data Structures
Announcements
- Proramming project 2 will be up today or
tomorrow. - The second OWL assignment is up - due 10/12/06
3Java 5 and Lists
- Generics
- Implementation of Linked List using an iterator
Normal List myIntList new LinkedList() myIntL
ist.add(new Integer(0)) Integer x (Integer)
myIntList.iterator().next()
With Generics ListltIntegergt myIntList new
LinkedListltIntegergt() myIntList.add(new
Integer(0)) Integer x myIntList.iterator().next
()
4Generics
Excerpts from the interfaces for List and
Iterator
- public interface ListltEgt
- void add(E x)
- IteratorltEgt iterator()
-
- public interface IteratorltEgt
- E next()
- boolean hasNext()
5Generic Collection ArrayListltEgt
- The ltEgt indicates a type parameter
- Here E can be any Object type
- Every element of ArrayListltEgt must obey E
- This is a Java 5.0 innovation
- Previously all lists held only objects
- ArrayListltEgt is more restrictive
- Catches more errors at compile time!
6Generic Collection ArrayListltEgt
- ListltStringgt lst new ArrayListltStringgt()
- ArrayListltIntegergt numList new
ArrayListltIntegergt() - lst.add(35) // will not type check
- numList.add(xyz) // will not type check
- numList.add(new Integer(35)) // ok
- numList.add(35) // also ok auto-boxes
7Why Use Generic Collections?
- Better type-checking catch more errors, earlier
- Documents intent
- Avoids downcast from Object
8How Did They Maintain Compatibility?
- Generics are strictly a compiler thing
- They do not appear in bytecode or anywhere else
- Compiler directives
- It is as if the lt...gt stuff is erased
- Called erasure semantics
- Can be completely ignored
- Programs without use of generics run fine
- May have some small effect on what we write but
well point those out as we go along.
9Example Application of ArrayList
- ArrayListltIntegergt someInts new
ArrayListltIntegergt() - int nums 5, 7, 2, 15
- for (int i 0 i lt nums.length i)
- someInts.add(numsi)
-
- int sum 0
- for (int i 0 i lt someInts.size() i)
- sum sum someInts.get(i)
-
- System.out.println(sum is sum)
10The LinkedList Class
- Part of the Java API
- Implements the List interface using a
double-linked list
11The Iterator Interface
- The Iterator interface is defined in java.util
- The List interface declares the method iterator
- Returns an Iterator object
- That iterates over the elements of that list
- An Iterator does not refer to a particular object
in the list at any time
12Picture of an Iterator
- Point An Iterator is conceptually between
elements
13The Iterator Interface (2)
14The Iterator Interface Typical Use
- ListltEgt lst ...
- IteratorltEgt iter lst.iterator()
- while (iter.hasNext())
- System.out.println(iter.next().toString())
-
- Alternatively (Java 5.0 for-each loop)
- for (E elem lst)
- System.out.println(elem.toString())
15Iterators and Removing Elements
- Interface Iterator supports removing void
remove() - What it deletes is the most recent element
returned - So, you must invoke next() before each remove()
- What about LinkedList.remove?
- It must walk down the list, then remove
- So in general it is O(n)
- Versus Iterator.remove, which is O(1) but
wait. - Further, you should not mix the two types of
modifications to the list structure - Most iterators fail, throwing ConcurrentModificati
onException, if you make changes to the list from
outside the iterator while it is running. - Originally iterators were designed for things
like output.
16The ListIterator Interface
- Iterator limitations
- Can traverse List only in the forward direction
- Provides remove method, but no add
- Must advance iterator using your own loop if not
starting from the beginning of the list - ListIterator adds to Iterator, overcoming these
limitations - As with Iterator, ListIterator best imagined as
being positioned between elements of the list
17The ListIterator Interface
18Imagining ListIterator
Position of iterator
19Obtaining a ListIterator
20Comparison of Iterator and ListIterator
- ListIterator is a subinterface of Iterator
- Classes that implement ListIterator provide all
the capabilities of both - Iterator
- Requires fewer methods
- Can iterate over more general data structures
- Iterator required by the Collection interface
- ListIterator required only by the List interface
21What ListIterator Adds
- Traversal in both directions
- Methods hasPrevious(), previous()
- Methods hasNext(), next()
- Obtaining next and previous index
- Modifications
- Method add(E) to add before cursor position
- Method remove() to remove last returned
- Method set(E) to set last returned
22Conversion Between ListIterator and Index
- ListIterator
- Method nextIndex() returns index of item to be
returned by next() - Method previousIndex() returns index of item to
be returned by previous() - Class LinkedList has method listIterator(int
index) - Returns a ListIterator positioned so next() will
return item at position index
23One More Interface Iterable
- Implemented by types providing a standard
Iterator - Allows use of Java 5.0 for-each loop
- public interface IterableltEgt
- IteratorltEgt iterator()
24Doubly Linked List Class
- Suppose we had a List Iterator class..couldnt
we implement many of the methods of the Linked
List class in terms of the List Iterator methods? - Section 4.6 in book..
- Lets look at the two interfaces again to see why
this might work..
25LinkedList Methods
26ListIterator Methods
27Double Linked List Class
- Implementation using an iterator
- Done in the book as well - terrible description!
- Well only hit the highlights
- Structure
class KWList ..data fields ..inner class
for Node ..inner class for Iterator .methods
for the KW class //end
private static class NodeltEgt .data fields
.methods
p. 217 book
private class KWListIter .data fields
.methods
28Doubly Linked List
0
1
2
3
4
29The Data Fields of the KWLinkedList Class
30The KWLinkedList Class
import java.util. / Class KWLinkedList
implements a subset of the List interface
using a doubly linked list and a
ListIterator. / public class KWLinkedList
extends AbstractSequentialList // Data
fields / A reference to the head of the list
/ private Node head null / A reference
to the end of the list / private Node tail
null / The size of the list / private int
size 0 methods and inner classes
//end KWLinkedList
Go look!
31The Node Class(inner class)
/ A Node is the building block for the linked
list / private static class Node / The
data value. / private Object data /
The link to the next node / private Node
next null / The link to the previous
node / private Node prev null /
Construct a node with the given data value
_at_param dataItem - The data value / private
Node(Object dataItem) data dataItem
32Implementing KWLinkedList
- Now assume we have an implementation of the
KWListInterator interface as an inner class.. - (Will do later)
- How can we implement the methods of the linked
list class using the iterator? - Consider the add method
33LinkedList Methods
34Adding in the middle of a list
0
1
2
3
4
35add(index, obj)
- / Add an item at the specified index.
- _at_param index - The index at which the
- object is to be inserted.
- _at_param obj - The object to be inserted.
- _at_throws IndexOutOfBoundsException -
- if the index is out of
- range (i lt 0 i gt size()) /
- public void add(int index, Object obj)
- listIterator(index).add(obj)
List add
Creates an anonymous list iterator positioned at
index
iterator add
36addFirst and addLast
/ Insert an object at the beginning of the
list. _at_param obj - the object to be added
/ public void addFirst(Object obj)
add(0, obj) / Insert an object at the
end of the list. _at_param obj - the object to
be added / public void addLast(Object obj)
add(size, obj)
37Getting an element at index
- / Get the element in the list specified by an
index - _at_param index The index of the element desired
- _at_return The value at the position specified
- /
- public Object get(int index)
- return listIterator(index).next()
-
38Removing an element at index
- / Remove an item at the specified index
returns removed item. - _at_param index - The index at which the object is
to be removed. - _at_throws IndexOutOfBoundsException - if the
index is out of range (i lt 0 i gt size()) - /
- public Object remove(int index)
- Object returnValue null
- ListIterator iter listIterator(index)
- if (iter.hasNext())
- returnValue iter.next()
- iter.remove()
-
- else
- throw new IndexOutOfBoundsException()
-
- return returnValue
-
39Returning a list iterator
- / Return a ListIterator to the list
- _at_return a ListItertor to the list
- /
- public ListIterator listIterator()
- return new KWListIter(0)
-
40Returning a list iterator
- / Return a ListIterator to the list positioned
at location index - _at_return a ListItertor to the list
- /
- public ListIterator listIterator(int index)
- return new KWListIter(index)
-
41So
- Most of the interesting work is in the list
iterator. - How do we write that?
- Make it an inner classwhy?