1 CMPSCI 187 Computer Science 187 Introduction to Introduction to Programming with Data Structures Lecture 8 Lists, Iterators, and Doubly Linked Lists Lecture 8 Lists, Iterators, and Doubly Linked Lists
2 CMPSCI 187 Computer Science 187 Introduction to Introduction to Programming with Data Structures AnnouncementsAnnouncements 1.Proramming project 2 will be up today or tomorrow. 2.The second OWL assignment is up - due 10/12/06
3 CMPSCI 187 Java 5 and Lists l Generics l Implementation of Linked List using an iterator Normal: List myIntList = new LinkedList(); myIntList.add(new Integer(0)); Integer x = (Integer) myIntList.iterator().next(); With Generics: List myIntList = new LinkedList (); myIntList.add(new Integer(0)); Integer x = myIntList.iterator().next();
4 CMPSCI 187 Generics public interface List { void add(E x); Iterator iterator(); } public interface Iterator { E next(); boolean hasNext(); } Excerpts from the interfaces for List and Iterator:
5 CMPSCI 187 Generic Collection ArrayList The indicates a type parameter Here E can be any Object type Every element of ArrayList must obey E l This is a Java 5.0 innovation Previously all lists held only objects ArrayList is more restrictive: H Catches more errors at compile time!
6 CMPSCI 187 Generic Collection ArrayList List lst = new ArrayList (); ArrayList numList = new ArrayList (); 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
7 CMPSCI 187 Why Use Generic Collections? l Better type-checking: catch more errors, earlier l Documents intent Avoids downcast from Object
8 CMPSCI 187 How Did They Maintain Compatibility? l Generics are strictly a compiler thing l They do not appear in bytecode or anywhere else F Compiler directives l It is as if the stuff is erased F Called erasure semantics l Can be completely ignored F Programs without use of generics run fine F May have some small effect on what we write but we’ll point those out as we go along.
9 CMPSCI 187 Example Application of ArrayList ArrayList someInts = new ArrayList (); int[] nums = {5, 7, 2, 15}; for (int i = 0; i < nums.length; ++i) { someInts.add(nums[i]); } int sum = 0; for (int i = 0; i < someInts.size(); i++) { sum = sum + someInts.get(i); } System.out.println(“sum is “ + sum);
10 CMPSCI 187 The LinkedList Class l Part of the Java API Implements the List interface using a double-linked list
11 CMPSCI 187 The Iterator Interface The Iterator interface is defined in java.util The List interface declares the method iterator Returns an Iterator object F That iterates over the elements of that list An Iterator does not refer to a particular object in the list at any time
12 CMPSCI 187 Picture of an Iterator Point: An Iterator is conceptually between elements
13 CMPSCI 187 The Iterator Interface (2)
14 CMPSCI 187 The Iterator Interface: Typical Use List lst =...; Iterator 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()); }
15 CMPSCI 187 Iterators and Removing Elements Interface Iterator supports removing: void remove() l What it deletes is the most recent element returned So, you must invoke next() before each remove() What about LinkedList.remove ? F It must walk down the list, then remove F So in general it is O(n) Versus Iterator.remove, which is O(1) [but wait….] F Further, you should not mix the two types of modifications to the list structure: Most iterators fail, throwing ConcurrentModificationException, if you make changes to the list from outside the iterator while it is running. l Originally iterators were designed for things like output….
16 CMPSCI 187 The ListIterator Interface Iterator limitations Can traverse List only in the forward direction Provides remove method, but no add F 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
17 CMPSCI 187 The ListIterator Interface
18 CMPSCI 187 Imagining ListIterator Position of iterator
19 CMPSCI 187 Obtaining a ListIterator
20 CMPSCI 187 Comparison of Iterator and ListIterator ListIterator is a subinterface of Iterator Classes that implement ListIterator provide all the capabilities of both Iterator : F Requires fewer methods F Can iterate over more general data structures Iterator required by the Collection interface ListIterator required only by the List interface
21 CMPSCI 187 What ListIterator Adds l Traversal in both directions Methods hasPrevious(), previous() Methods hasNext(), next() l Obtaining next and previous index l Modifications: Method add(E) to add before “cursor” position Method remove() to remove last returned Method set(E) to set last returned
22 CMPSCI 187 Conversion 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
23 CMPSCI 187 One More Interface: Iterable Implemented by types providing a standard Iterator l Allows use of Java 5.0 for-each loop public interface Iterable { Iterator iterator(); }
24 CMPSCI 187 Doubly Linked List Class l Suppose we had a List Iterator class…..couldn’t we implement many of the methods of the Linked List class in terms of the List Iterator methods? l Section 4.6 in book….. l Let’s look at the two interfaces again to see why this might work…..
25 CMPSCI 187 LinkedList Methods
26 CMPSCI 187 ListIterator Methods
27 CMPSCI 187 Double Linked List Class l Implementation using an iterator l Done in the book as well - terrible description! l We’ll only hit the highlights l Structure: class KWList { …..data fields …..inner class for Node …..inner class for Iterator ….methods for the KW class } //end private static class Node { ….data fields ….methods } private class KWListIter { ….data fields ….methods } p. 217 book
28 CMPSCI 187 Doubly Linked List 01234
29 CMPSCI 187 The Data Fields of the KWLinkedList Class
30 CMPSCI 187 The 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!
31 CMPSCI 187 The 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 dataItem - The data value */ private Node(Object dataItem) { data = dataItem; }
32 CMPSCI 187 Implementing KWLinkedList l Now assume we have an implementation of the KWListInterator interface as an inner class….. (Will do later) l How can we implement the methods of the linked list class using the iterator? l Consider the add method
33 CMPSCI 187 LinkedList Methods
34 CMPSCI 187 Adding in the middle of a list 01234
35 CMPSCI 187 add(index, obj) /** Add an item at the specified index - The index at which the object is to be obj - The object to be IndexOutOfBoundsException - if the index is out of range (i size()) */ public void add(int index, Object obj) { listIterator(index).add(obj);} List add iterator add Creates an anonymous list iterator positioned at index
36 CMPSCI 187 addFirst and addLast /** Insert an object at the beginning of the obj - the object to be added */ public void addFirst(Object obj) { add(0, obj); } /** Insert an object at the end of the obj - the object to be added */ public void addLast(Object obj) { add(size, obj); }
37 CMPSCI 187 Getting an element at index /** Get the element in the list specified by an index The index of the element The value at the position specified */ public Object get(int index) { return listIterator(index).next(); }
38 CMPSCI 187 Removing an element at index /** Remove an item at the specified index; returns removed index - The index at which the object is to be IndexOutOfBoundsException - if the index is out of range (i 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; }
39 CMPSCI 187 Returning a list iterator /** Return a ListIterator to the a ListItertor to the list */ public ListIterator listIterator() { return new KWListIter(0); }
40 CMPSCI 187 Returning a list iterator /** Return a ListIterator to the list positioned at location a ListItertor to the list */ public ListIterator listIterator(int index) { return new KWListIter(index); }
41 CMPSCI 187 So…… l Most of the interesting work is in the list iterator. l How do we write that? l Make it an inner class……why?