import java.util.NoSuchElementException; /** * * @author latimer * @version 1.00 03/03/16 * * Example of an Iterator for the LinkedPositionalList class. * */ public class Alphabet { private LinkedPositionalList alphabet = null; // // Constructor builds a LinkedPositionalList of Letters. // public Alphabet( ){ alphabet = new LinkedPositionalList<>(); String alphabetString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; Letter nextLetter; for ( int i = 0; i < alphabetString.length(); i++ ) { nextLetter = new Letter( alphabetString.charAt(i) ); alphabet.addLast( nextLetter ); } } public boolean isVowel( String s ) { return ( s.equals("A") || s.equals("E") || s.equals("I") || s.equals("O") || s.equals("U") ); } // // This method uses an iterator to traverse the list. // // Note that here we are using the nested iterator classes from the // LinkedPositionalList class and not ones for the Alphabet class. // @Override public String toString( ) { String returnString = ""; Iterator listIterator = alphabet.iterator(); while ( listIterator.hasNext() ) returnString += listIterator.next() + " "; return returnString; } // // The following classes are the nested Iterator classes from // Code Fragment 7.14 // // Only the classes for the Position Itertor have bee included. // // These fragements have been modified so that they are specific to the // Alphabet class. // // It is necessary to put the iterator code here since we want to create // iterators specifically for the Alphabet class which is a concrete class // based on the generic ADT LinkedPositionalList. // // Our code needs to have knowledge of Letter. // // Generally the Generic placeholders have been replaced with // concret references // AND // Call to LinkedPositionalList methods have be replaced by calls using // the instance reference alphabet // e.g. // private Position cursor = first(); // became // private Position cursor = alphabet.first(); // //----- nested PositionIterator class ----- private class PositionIterator implements Iterator>{ private Position cursor = alphabet.first(); // position of the next element to report private Position recent = null; // position of last reported element /** Tests whether the iterator has a next object. */ @Override public boolean hasNext( ) { return ( cursor != null ); } /** Returns the next position in the iterator. */ @Override public Position next( ) throws NoSuchElementException { if ( cursor == null ) throw new NoSuchElementException( "nothing left " ); recent = cursor; cursor = alphabet.after( cursor ); return recent; } /** Removes the element returned by most recent call to next. */ @Override public void remove( ) throws IllegalStateException { if ( recent == null ) throw new IllegalStateException( "nothing to remove" ); alphabet.remove( recent ); // remove from outer list recent = null; // do not allow remove again until next is called } } //----- end of nested PositionIterator class ----- //----- nested PositionIterable class ----- private class PositionIterable implements Iterable>{ @Override public Iterator> iterator( ) { return new PositionIterator( ); } } //----- end of nested PositionIterable class ----- /** Returns an iterable representation of the list's positions. * @return */ public Iterable> positions( ) { return new PositionIterable( ); // create a new instace of the inner class } // // Below are the nested iterator classes modified to iterate over just the // vowels in a the alphabet list // // Aside from taking care of name conflicts the only real modification // that is necessary is in the next() method betweeen the lines: // recent = cursor; // << modification goes here // return recent; // // This is because cursor points to the Position that will be returned // the "next" time next() is called so: // after saving the value of cursor to recent // cursor is advanced to the next desired location // -- you customize where the cursor is advanced to. // then the value of recent is returned. // // You can create additional custom iterators by making additional copies // of the nested iterator classes, adjusting the names, and modifying // how the value of cursor is updated on each call to next(). // //----- nested PositionIterator class ----- private class VowelPositionIterator implements Iterator>{ private Position cursor = alphabet.first(); // position of the next element to report private Position recent = null; // position of last reported element /** Tests whether the iterator has a next object. */ @Override public boolean hasNext( ) { return ( cursor != null ); } /** Returns the next position in the iterator. */ @Override public Position next( ) throws NoSuchElementException { // On the first call to next (i.e. when recent == null) you need to //<<< new code // advance recent until it is pointing to a vowel element. //<<< new code if ( recent == null ) //<<< new code { //<<< new code while ( cursor != null && !isVowel( cursor.getElement().letter) ) //<<< new code cursor = alphabet.after( cursor ); //<<< new code } //<<< new code if ( cursor == null ) throw new NoSuchElementException( "nothing left " ); recent = cursor; cursor = alphabet.after( cursor ); // advance cursor to the next vowel while ( cursor != null && !isVowel( cursor.getElement().letter) ) cursor = alphabet.after( cursor ); return recent; } /** Removes the element returned by most recent call to next. */ @Override public void remove( ) throws IllegalStateException { if ( recent == null ) throw new IllegalStateException( "nothing to remove" ); alphabet.remove( recent ); // remove from outer list recent = null; // do not allow remove again until next is called } } //----- end of nested PositionIterator class ----- //----- nested PositionIterable class ----- private class VowelPositionIterable implements Iterable>{ @Override public Iterator> iterator( ) { return new VowelPositionIterator( ); } } //----- end of nested PositionIterable class ----- /** Returns an iterable representation of the list's positions. * @return */ public Iterable> vowelPositions( ) { return new VowelPositionIterable( ); // create a new instace of the inner class } }