Details of the java iteration subpattern

  • 2020-05-05 11:14:32
  • OfStack

Structure of the iteron (Iterator) pattern:
The iterative subpattern can access elements in an aggregation sequentially without exposing the inner representation of the aggregation.
Iterators can be divided into outer iterator and inner iterator .
outer iterator: is suitable for white box aggregation (which is the aggregation that provides the outside world with access to its internal element interface). Since the logic of the iteration is provided by the aggregation object itself, such outer iterator roles tend to only keep the cursor position of the iteration. So the concrete iterator subrole is an external class whose constructor accepts a concrete aggregate object and thus can call the iterating logic of the aggregate object.
inner iterator: is suitable for black box aggregation (black box aggregation does not provide an external interface to iterate over its own element objects). Since the element objects of black box aggregation can only be accessed by the inner members of the aggregation, inner iterators can only be subclasses of members within the aggregation.
Simple demonstration:


package test.edu.inter; 
 
public interface IteratorObj { 
  
  /** 
  *  Move to the first element  
  */ 
 public void first(); 
 /** 
  *  Move to the next element  
  */ 
 public boolean hasNextItem(); 
 /** 
  *  Return the current element  
  */ 
 public Object currentItem(); 
 
} 


package test.edu.inter; 
 
public interface DataSet { 
 public IteratorObj getIterator(); 
} 



package test.edu.inter; 
 
 
public class Iterator1 implements IteratorObj { 
  
 private Dataobj set; 
 private int size; 
 private int index=0; 
  
 public Iterator1(Dataobj set){ 
  this.set = set; 
  this.size = set.getSize(); 
 } 
 
 @Override 
 public void first() { 
  // TODO Auto-generated method stub 
  this.index = 0; 
 } 
  
 @Override 
 public boolean hasNextItem() { 
  if(index<size){ 
   return true; 
  } 
  return false; 
 } 
 
 @Override 
 public Object currentItem() { 
  Object ob = set.getItem(index); 
  if(index<size){ 
   index++; 
  } 
  return ob; 
 } 
} 



package test.edu.inter; 
 
public class Dataobj implements DataSet { 
  
 private Object[] objArray = null; 
  /** 
   *  Passing in the aggregate object  
   */ 
 public Dataobj(Object[] objArray){ 
   this.objArray = objArray; 
  } 
  
 @Override 
 public IteratorObj getIterator() { 
  return new Iterator1(this); 
 } 
  
 public Object getItem(int index){ 
  return objArray[index]; 
 } 
 public int getSize(){ 
  return objArray.length; 
 } 
} 



package test.edu.inter; 
 
public class Client { 
 
 /** 
  * @param args 
  */ 
 public static void main(String[] args) { 
  // TODO Auto-generated method stub 
  String[] str={"12312","dasda","dasd","12d","asd"}; 
  Dataobj ao = new Dataobj(str); 
  IteratorObj io = ao.getIterator(); 
  while(io.hasNextItem()){ 
   System.out.println(io.currentItem()); 
  } 
 } 
} 

Result :


12312 
dasda 
dasd 
12d 
asd 

content expansion:
application of
in java aggregation in java.util.Collection interface provides iterator() factory method to return an Iterator type object, Collection interface of the child type AbstractList class of the internal member class Itr implements Iterator interface. So Itr is an inner iterated subclass, but AbstractList also provides its own traversal method, so it's not black box clustering, but white box clustering. The code is as follows:


import java.util.Iterator;
public interface Itr extends Iterator{
   // Call again next() The index used in the method 
   int cursor = 0;
   // The metric used in the last invocation 
   int lastRet = -1;
   int expectedModCount = modCount;
   public boolean hasNext(){
     return cursor!=size();
   }
   public Object next(){
     try{
       Object next = get(cursor);
       checkForComodification();
       lastRet = cursor++;
       return next;
     }catch(IndexOutOfBoundsException e){
       checkForComodification();
       throw new NoSuchElementException();
     }
   }
   // Delete the last element traversed, remove() Method can only delete the last element traversed 
   public void remove(){
     if(lastRet ==-1)
       throw new IllegalStateException();
     checkForComodification();
     try{
       AbstractList.this.remove(lastRet);
       if(lastRet<cursor)
          cursor--;
       lastRet = -1;
       expectedModCount = modCount;
     }catch(IndexOutOfBoundsException e){
       throw new ConcurrentModificationException();
     }
   }
   public void checkForComodification(){
     if(modCount!=expectedModCount)
       throw new ConcurrentModificationException();
   }
}

Among them, modCount, get(cursor) and other variables and methods are owned by AbstractList class, and Itr can be directly used. The method checkForComodification() checks to see if the aggregated content has just been modified directly by the outside world (not by the remove() method provided by the iterator). This method immediately throws an exception if, after the iteration starts, the aggregated content is modified by the outside world directly bypassing the iteration child object.
Also: the AbstractList class also provides the listIterator() method, which returns an instance of the ListItr class that implements the Listiterator interface. The ListIterator interface implements forward and reverse iterations, and provides a way to safely modify the contents of the column during the iteration.
The difference between Enumeration and Iterator :(1) Enumeration does not have remove method (2) Enumeration is implemented in Vector's element() method with an unnamed class. Enumeration does not pay Fail Fast. That is to say, during the iteration, the aggregate object is accidentally modified directly by the outside world.

The above is the entire content of this article, I hope to help you with your study.


Related articles: