Wednesday, 2 April 2014

Iterator pattern

Provides a way to access the elements of an aggregate object without exposing its underlying representation.

This pattern is used to get a way to access the elements of a collection object in sequential manner without any need to know its underlying representation.


Suppose I have a list of cities in a arraylist .and I want to access them. Java collection framework provides listIterator.

public class TestListIterator {

      public static void main1(String[] args) {

            ArrayList<String> cities = new ArrayList<String>();
            cities.add("Bhopal");
            cities.add("Indore");
            cities.add("Sehore");
            cities.add("Ujjain");

            ListIterator<String> it = cities.listIterator();

            while (it.hasNext()) {
                  System.out.println(it.next());
            }

      }

Suppose I have a list of cities in a array not arraylist and I want to access them.
In this case I have to write my own Iterator. Basically Iterator is an Iterface.

package java.util;

/**
 An iterator over a collection.  Iterator takes the place of Enumeration in the Java collections framework.  Iterators differ from enumerations in two  ways:
  1. Iterators allow the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
  2. Method names have been improved.
*/
public interface Iterator<E> {
    boolean hasNext();
    E next();
    void remove();
}

public class TestListIterator{
      public static void main(String[] args) {

      final String[] cities = new String[] { "Bhopal", "Indore", "Sehore","Ujjain" };

            Iterator<String> it = new Iterator<String>() {

                  int count = 0;

                  @Override
                  public void remove() {  }

                  @Override
                  public String next() {
                        return cities[count++];
                  }

                  @Override
                  public boolean hasNext() {
                  if (cities.length > count && cities[count] != null) {
                              return true;
                        }
                        return false;
                  }
            };

            while (it.hasNext()) {
                  System.out.println(it.next());
            }
      }
}


I have implemented Iterator interface in anonymous inner class. Here cities is final as I am using them inside a inner class.

Observe the highlighted code (it.hasNext()) is same in this two

Now I want a state object which stores cities inside it. And I will provide the iterator to Iterate this State object.


public class City {

      private String cityName;
      private String state;

      public City(String name, String state) {
            this.state = state;
            this.cityName = name;
      }

      public String getName() {
            return cityName;
                 
      }

      public void print() {
            System.out.println("Name: " + cityName + " Division: " + state);
      }

}

public class State {

      private City[] cities = new City[100];

      private String stateName;

      private int cityCount = 0;

      public State(String stateName) {
            this.stateName = stateName;

      }

      public void add(String vpName) {
            City vp = new City(vpName, stateName);
            cities[cityCount++] = vp;
      }

      public String getName() {
            return stateName;
      }

      /*
       * Similar to  a listIterator
       */
      public Iterator<City> stateIterator() {
            return new StateIterator(cities);
      }
}





class StateIterator implements Iterator {

      private City[] cities;

      int count = 0;

      public StateIterator(City[] cities) {
            this.cities = cities;
      }

      public StateIterator() {
      }

      @Override
      public boolean hasNext() {
            if (cities.length > count && cities[count] != null) {
                  return true;
            }
            return false;
      }

      @Override
      public Object next() {
            return cities[count++];
      }

      @Override
      public void remove() {
      }

}



public class TestStateIterator{
     
      public static void main(String[] args) {
           
            State mp = new State("MP");
           
            mp.add("Bhopal");
            mp.add("Indore");
            mp.add("Sehore");
     
          Iterator<City>  it = mp.stateIterator();
           
          while(it.hasNext()){
            it.next().print();
          }
     
      }
     
}

Compare this code with TestListIterator code(First One) . You will find no difference in accessing the arraylist and state object because both are providing an Iterator object.


Here Iterator pattern Provides a way to access the elements of an aggregate object (State Object ) without exposing its underlying representation.

This pattern is used to get a way to access the elements of a collection object (State Object ) in sequential manner without any need to know its underlying representation.





No comments:

Post a Comment