1 / 22

Iteration Abstraction

This article discusses the importance of iteration abstraction in software construction, specifically in the context of common collections such as lists, sets, and maps. It explores different approaches for visiting each element in a collection and highlights the benefits of using the Iterator interface. The implementation details and examples are provided to illustrate the concepts.

brantner
Download Presentation

Iteration Abstraction

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Iteration Abstraction SWE 619 - Software Construction Fall 2009

  2. Common Collections • List (Interface) • AbstractList • ArrayList, Linked List, Vector • Set (Interface) • AbstractSet • HashSet, TreeSet • Map (Interface) • AbstractMap • HashMap, TreeMap • Arrays • Stack -subtype of Vector (Anomaly?)

  3. Visiting each element of a collection • Scenario: A common container has several objects stored • Task: To visit each element in the container • HOW?

  4. Approaches • IntSet choose() method? • Remove – choose combination • What is the problem here? • Return the collection? • Why is this bad? • Return a clone? • Is this better?

  5. Approaches • Custom built method? • Close, but not it • Problem? Not general • We want uniformity • Iteration Abstraction • Client code is simplified, using is easy • Implementation may be complex, but standard

  6. Iterator Interface public Interface Iterator { public boolean hasNext(); public Object next() throws NoSuchElementException; public void remove() throws IllegalStateException; } • Liskov has only first hasNext() and next() • To satisfy the compiler, you need to override/implement remove() too

  7. Specification public boolean hasNext() ; // Effects: Returns true if there are more elements to yield else returns false public Object next(); // Modifies: this // Effects: If there are more results to yield, returns the next result and modifies the state of this to record the yield. Otherwise, throws NoSuchElementEx.

  8. Definitions An iterator is a procedure that returns a generator. A data abstraction can have one or more iterator methods, and there can also be standalone iterators. A generator is an object that produces the elements used in the iteration. The generator’s type is a subtype of Iterator. The specification of an iterator defines the behavior of the generator; a generator has no specification of its own. The iterator specification often includes a requires clause at the end constraining the code that uses the generator.

  9. Examples: Poly and IntSet public Iterator terms() // Effects: Returns a generator that will produce exponents // of nonzero terms of this (as Integers) up to the degree, // in order of increasing exponent public Iterator elements() // Effects: Returns a generator that will produce all the elements // of this (as Integers) each exactly once, in arbitrary order // Requires: this must not be modified while the // generator is in use

  10. Example: Poly Poly p … // p = 2 + 3 x2+ 4 x5 Iterator itr = p.iterator(); // Usual Iterator itr = p.terms(); // Liskov’s itr = [0,2,5] itr.hasNext() // return true, itr = [0,2,5] itr.next() // return 0, itr = [2,5] itr.next() // return 2, itr = [5] itr.hasNext() // return true, itr = [5] itr.next() // return 5, itr = [] itr.hasNext() // return false, itr = [] itr.next() // return NSEE, itr = []

  11. Abstraction Function • It’s the current list of things that you are going to send back • Very close to a Stack • top = next() element • remove() adds complexity • If multiple interfaces, iterator may not know about removed items! • Only mutable data types are affected

  12. Af(c) for Poly Iterator Poly p … // p = 2 + 3 x2+ 4 x5 AF(itr.hasNext()) = [0,2,5] //true AF(itr.next()) = [2,5] //0 AF(itr.next()) = [5] //2 AF(itr.hasNext()) = [5] //true AF(itr.next()) = [] //5 AF(itr.hasNext()) = [] //false AF(itr.next()) = [] //NSEE

  13. Implementation (Fig 6.8) public class Poly{ // Rep … public Iterator terms() {return new PolyGen(this);} // inner class private static class PolyGen implements Iterator { private Poly p; // the Poly being iterated private int n; // the next term to consider PolyGen (Poly it){ //Requires: it !=null p = it; if(p.trms[0] == 0) n=1; else n= 0; }

  14. Implementation (contd.) public boolean hasNext() {return n<= p.deg;} public Object next () throws NSEE{ for(int e = n; e <= p.deg; e++) { if (p.trms[e] != 0) { n= e+1; return new Integer(e); } } throw new NSEE(“Poly.terms”); } // end PolyGen }

  15. Inner Class • private class • visibility only inside the class where defined • no outside code can see/instantiate it • if it has public methods && an instance available, outside code can call it

  16. State for iterator • How to figure out the state? • Same way as AF(c) for Data Abstraction • Ask yourself: What do I need to send back to the client? • Example Rep state: [2,0,3,0,0,4] • What if PolyGen was immutable?

  17. Another example: PrimesGen private static class PrimesGen implements Iterator{ private Vector ps; // primes yielded private int p; // next candidate to try PrimesGen () { p =2 ; ps = new Vector();} //constructor public boolean hasNext() {return true;} // always true public Object next() throws NSEE { if (p==2) {p=3; return 2;} for (int n=p; true; n = n+2){ … //Prime number generation } } }// end of PrimesGen

  18. Abstract State for PrimesGen? Iterator itr = num.allPrimes(); AF(c) = [2,3,5,7,11,13,17,19, …] • No end? Can we figure out the length of the tail? • What does hasNext() have to do in this case? [2,3,5,7,9,…] Integer x = (Integer) itr.next(); [3,5,7,9,11,..] Integer y = (Integer) itr.next(); [5,7,9,11,13,17,…] . .

  19. Exercises • What if there is an upper bound on the prime numbers? • Suppose primes <100. • What will be AF(c) be like? • What will hasNext() implementation do? • How will implementation of PrimesGen change?

  20. Another Exercise public Interface TwoWayIterator { Object next (); Object previous (); boolean hasNext(); boolean hasPrevious(); • Suppose we want to go back AND forward • What does the abstraction function look like? • Still a stack? • What other state information is needed? • How to implement this for Poly?

  21. What about supporting remove()? • The contract for remove(): Removes from the underlying collection the last element returned by the iterator (optional operation). This method can be called only once per call to next. The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method. • This is complex! • What is the new abstract state?

  22. Iterable vs. Iterator • Only one method required: • public Iterator<T> iterator(); • Allows very nice code: // Note: that Collection implements Iterable // Side note: String does NOT implement Iterable Set<String> mySet = new HashSet<String>(); // populate mySet with various Strings for (String s : mySet) { // auto invocation of iterator(), next() // do something with s }

More Related