Upload
others
View
7
Download
0
Embed Size (px)
Citation preview
Some useful interface for iterators
Iterators
• An iterator is an object that is used with a collection to provide sequential access to the collection elements • This access allows examination and possible modification of the elements
• An iterator imposes an ordering on the elements of a collection even if the collection itself does not impose any order on the elements it contains • If the collection does impose an ordering on its elements, then the
iterator will use the same ordering
16-2 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
The Iterator<T> Interface
• Java provides an Iterator<T> interface • Any object of any class that satisfies the Iterator<T> interface is an Iterator<T>
• An Iterator<T> does not stand on its own • It must be associated with some collection object using the method iterator
• If c is an instance of a collection class (e.g., HashSet<String>), the following obtains an iterator for c: Iterator iteratorForC = c.iterator();
16-3 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
Methods in the Iterator<T> Interface (Part 1 of 2)
16-4 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
Methods in the Iterator<T> Interface (Part 2 of 2)
16-5 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
Optional Operations in some interfaces
• When an interface lists a method as "optional," it must still be implemented in a class that implements the interface • The optional part means that it is permitted to write a method that does not
completely implement its intended semantics
• However, if a trivial implementation is given, then the method body should throw an UnsupportedOperationException
16-6 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
public class ArrayListWithIterator {// Iterator interface is in java.util public static void main(String args[]){ ArrayList<String> myList = new ArrayList<String>(); Iterator<String> anIterator ; myList.add("health"); myList.add("love"); myList.add("money"); myList.add("that"); myList.add("is"); myList.add("all"); System.out.println("The list has " + myList); // [health, love, money, that, is, all] anIterator = myList.iterator(); System.out.println("Traversing the list using an iterator "); while (anIterator.hasNext()){ System.out.println(anIterator.next()); } anIterator = myList.iterator(); // There is no reset operation in Iterator. We are now at the beginning anIterator.next(); anIterator.next(); // Current element "love" anIterator.remove(); // "love" is gone!! Now next() will retrieve "money" System.out.println("Traversing the list from the element containing money"); while (anIterator.hasNext()){ System.out.println(anIterator.next()); } }}
Output produced: The list has [health, love, money, that, is, all] Traversing the list using an iterator health love money that is all Traversing the list from the element containing money money that is all
The ListIterator<T> Interface
• The ListIterator<T> interface extends the Iterator<T> interface, and is designed to work with collections that satisfy the List<T> interface • A ListIterator<T> has all the methods that an Iterator<T> has,
plus additional methods • A ListIterator<T> can move in either direction along a list of elements • A ListIterator<T> has methods, such as set and add, that can be
used to modify elements
16-9 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
Methods in the ListIterator<T> Interface (Part 1 of 4)
16-10 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
Methods in the ListIterator<T> Interface (Part 2 of 4)
16-11 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
Methods in the ListIterator<T> Interface (Part 3 of 4)
16-12 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
Methods in the ListIterator<T> Interface (Part 4 of 4)
16-13 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
The ListIterator<T> Cursor
• Every ListIterator<T> has a position marker known as the cursor • If the list has n elements, they are numbered by indices 0 through n-1, but there are n+1
cursor positions
• When next() is invoked, the element immediately following the cursor position is returned and the cursor is moved forward one cursor position
• When previous() is invoked, the element immediately before the cursor position is returned and the cursor is moved back one cursor position
16-14 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
ListIterator<T> Cursor Positions
16-15 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved
public class ArrayListWithListIterator{ public static void main(String args[]){ ArrayList<String> myList = new ArrayList<String>(); ListIterator<String> anIterator ; myList.add("health"); myList.add("love"); myList.add("money"); myList.add("that"); myList.add("is"); myList.add("all"); System.out.println("The list has " + myList); anIterator = myList.listIterator(); // Everything we did in earlier example can be done here as well while (anIterator.hasNext()){ anIterator.next(); } // Now the cursor is beyond the last element. System.out.println("Traversing the list backwards using a list iterator"); while (anIterator.hasPrevious()){ System.out.println(anIterator.previous()); // each call gets the element before the // cursor position and moves the cursor one place left } // When the loop terminates we are at the beginning (See Display 16.16 in book)
anIterator.next(); anIterator.next(); // This call to next() returns "love" anIterator.remove(); // "love" is gone!! The element returned by last call to next() or previous() will be gone anIterator.next(); // retrieves "money" anIterator.add("fame"); // cannot be called right after another add or remove // adds "fame" after "money" and before "that" System.out.println("Traversing the list from the element containing money"); while (anIterator.hasNext()){ System.out.println(anIterator.next()); } System.out.println("The new list has " + myList); } }
Output produced: The list has [health, love, money, that, is, all] Traversing the list backwards using a list iterator all is that money love health Traversing the list from the element containing money that is all The new list has [health, money, fame, that, is, all]
How to ensure that the class you are defining will give you the ability to use an iterator?
One way, if you are happy with Iterator<T> interface for traversing your data structure, use Iterable
interface.
The interface contains only one method:
Iterator<T> iterator()
Returns an iterator over a set of elements of type T.
A class that implements this interface gives us access to an object that implements the Iterator
interface. You can then use the methods in that interface for your traversal.
Interface Iterable<T>
public class IterableList implements Iterable<Object>{ /* This is just to show how Iterable works. This is not a good definition. * It does not allow multiple iterators to work on the list simultaneously. */ ListGeneral aList; public class MyIterator implements Iterator<Object>{// Inner iterator class public Object next(){ Object value; value = aList.currentValue(); aList.getNextNode(); return value; } public boolean hasNext(){ return !aList.endOfList(); } public void remove() throws UnsupportedOperationException{ throw new UnsupportedOperationException(); } }
public Iterator<Object> iterator(){ MyIterator anIterator; anIterator = new MyIterator(); aList.restart(); // pointing to the beginning of list return anIterator; } public IterableList(){ aList = new ListGeneral(); } public void add(Object value){ // object is added to the end of list for(aList.restart(); !aList.endOfList(); aList.getNextNode()); aList.addBeforeCurrent(value); } public String toString(){ return aList.toString(); } }
public class IterableListTester { public static void main(String args[]){ IterableList aList; Iterator<Object> anIterator; aList = new IterableList(); aList.add("John"); aList.add("Mary"); aList.add("Tom"); aList.add("Paul"); System.out.println("Check contents of list"); System.out.println(aList); anIterator = aList.iterator(); System.out.println("What the iterator returns"); while(anIterator.hasNext()){ System.out.println(anIterator.next()); } } }
Output produced: Check contents of list John Mary Tom Paul What the iterator returns John Mary Tom Paul
Now we can use multiple things we have learned. We can define a new interface that specifies what we want to do: - We want to add a new object using add method - We want to be able to get an iterator object by calling the iterator method Idea: Program to an interface not to a class. That way we can easily future proof our code.
import java.util.*; // define an interface that specfies what we want to do public interface AddAndIterate<T> extends Iterable<T> { public void add(T x); }
public class IterableList1 implements AddAndIterate<Object>{ /* This is just like IterableList. Only difference is that we are trying to generalize our code.*/ ListGeneral aList; public class MyIterator implements Iterator<Object>{ public Object next(){ Object value; value = aList.currentValue(); aList.getNextNode(); return value; } public boolean hasNext(){ return !aList.endOfList(); } public void remove()throws UnsupportedOperationException{ throw new UnsupportedOperationException(); } } public Iterator<Object> iterator(){ MyIterator anIterator; anIterator = new MyIterator(); aList.restart(); // pointing to the beginning of list return anIterator; }
public IterableList1(){ aList = new ListGeneral(); } public void add(Object value){ // object is added to the end of list for(aList.restart(); !aList.endOfList(); aList.getNextNode()); aList.addBeforeCurrent(value); } public String toString(){ return aList.toString(); } }
public class IterableListTester { public static void main(String args[]){ AddAndIterate aList; // NOTE CHANGE!! aList is of the interface type Iterator<Object> anIterator; aList = new IterableList1(); // This is the only line that we need to change to have a different data structure aList.add("John"); // rest of code is the same as before aList.add("Mary"); aList.add("Tom"); aList.add("Paul"); System.out.println("Check contents of list"); System.out.println(aList); anIterator = aList.iterator(); System.out.println("What the iterator returns"); while(anIterator.hasNext()){ System.out.println(anIterator.next()); } } }
Output produced: (Same as before) Check contents of list John Mary Tom Paul What the iterator returns John Mary Tom Paul
Tip: Defining Your Own Iterator Classes
• There is usually little need for a programmer defined Iterator<T> or ListIterator<T> class
• The easiest and most common way to define a collection class is to make it a derived class of one of the library collection classes • By doing this, the iterator() and listIterator() methods automatically become
available to the program
• If a collection class must be defined in some other way, then an iterator class should be defined as an inner class of the collection class
16-30 Copyright © 2008 Pearson Addison-
Wesley. All rights reserved