Iterator Pattern

Posted by austine_power007 on Tue, 15 Feb 2022 12:25:33 +0100

Iterator Pattern

  • It's Java and Net programming environment. This pattern is used to access the elements of the collection object sequentially without knowing the underlying representation of the collection object.

  • Iterator patterns are behavioral patterns.

  • If our collection elements are implemented in different ways, including arrays, java collection classes, or other ways, when the client wants to traverse these collection elements, it needs to use a variety of traversal methods, and the internal structure of the elements will be exposed. We can consider using the iterator mode. It provides a unified interface for traversing set elements. It traverses set elements in a consistent way without knowing the underlying representation of set objects, that is, it does not expose its internal structure

case

The composition of the school's departments is displayed on one page. A school has multiple colleges and a college has multiple departments.

public class Department {
	private String name;
	private String desc;
	public Department(String name, String desc) {
		super();
		this.name = name;
		this.desc = desc;
	}
	public String getName() { return name; }
	public void setName(String name) { this.name = name; }
	public String getDesc() { return desc; }
	public void setDesc(String desc) { this.desc = desc; }
}
public class ComputerCollegeIterator implements Iterator {
	//Here we need how the Department stores the = > array
	Department[] departments;
	int position = 0; //Traversal position
	public ComputerCollegeIterator(Department[] departments) { this.departments = departments; }
	//Determine whether there is another element
	@Override
	public boolean hasNext() {
		if(position >= departments.length || departments[position] == null) {
			return false;
		}else {
			return true;
		}
	}
	@Override
	public Object next() { 
		Department department = departments[position];
		position += 1;
		return department;
	}
	//The deletion method is empty by default
	public void remove() { }
}
public class InfoColleageIterator implements Iterator {
	List<Department> departmentList; // The school of information engineering is the Department of information technology
	int index = -1;//Indexes
	public InfoColleageIterator(List<Department> departmentList) { this.departmentList = departmentList; }
	//Determine whether there is a next element in the list
	@Override
	public boolean hasNext() {
		if(index >= departmentList.size() - 1) {
			return false;
		} else {
			index += 1;
			return true;
		}
	}
	@Override
	public Object next() {
		return departmentList.get(index);
	}
	//Empty implementation remove
	public void remove() { }
}
public interface College {
	public String getName();
	//Method of adding system
	public void addDepartment(String name, String desc);
	//Returns an iterator, traversing
	public Iterator  createIterator();
}
public class ComputerCollege implements College {
	Department[] departments;
	int numOfDepartment = 0 ;// Save the number of objects in the current array
	public ComputerCollege() {
		departments = new Department[5];
		addDepartment("Java major", " Java major ");
		addDepartment("PHP major", " PHP major ");
		addDepartment("Big data specialty", " Big data specialty ");
	}
	@Override
	public String getName() { return "school of computing"; }
	@Override
	public void addDepartment(String name, String desc) {
		Department department = new Department(name, desc);
		departments[numOfDepartment] = department;
		numOfDepartment += 1;
	}
	@Override
	public Iterator createIterator() {
		return new ComputerCollegeIterator(departments);
	}
}
public class InfoCollege implements College {
	List<Department> departmentList;
	public InfoCollege() {
		departmentList = new ArrayList<Department>();
		addDepartment("Information Security Major", " Information Security Major ");
		addDepartment("Network security major", " Network security major ");
		addDepartment("Server security", " Server security ");
	}
	@Override
	public String getName() { return "School of Information Engineering"; }
	@Override
	public void addDepartment(String name, String desc) {
		Department department = new Department(name, desc);
		departmentList.add(department);
	}
	@Override
	public Iterator createIterator() { return new InfoColleageIterator(departmentList); }
}
public class OutPutImpl {
	//College collection
	List<College> collegeList;
	public OutPutImpl(List<College> collegeList) {
		this.collegeList = collegeList;
	}
	//Go through all the colleges, and then call printDepartment to export the departments of different colleges.
	public void printCollege() {
		//Take out all colleges from the collegeList. The List in Java has implemented Iterator
		Iterator<College> iterator = collegeList.iterator();
		while(iterator.hasNext()) {
			//Take out a college
			College college = iterator.next();
			System.out.println("=== "+college.getName() +"=====" );
			printDepartment(college.createIterator()); //Get the corresponding iterator
		}
	}
	
	//College output
	public void printDepartment(Iterator iterator) {
		while(iterator.hasNext()) {
			Department d = (Department)iterator.next();
			System.out.println(d.getName());
		}
	}
}
public class Client {
	public static void main(String[] args) {
		//Create College
		List<College> collegeList = new ArrayList<College>();
		ComputerCollege computerCollege = new ComputerCollege();
		InfoCollege infoCollege = new InfoCollege();
		
		collegeList.add(computerCollege);
		//collegeList.add(infoCollege);
		
		OutPutImpl outPutImpl = new OutPutImpl(collegeList);
		outPutImpl.printCollege();
	}
}

Source code analysis of iterator pattern in JDK ArrayList set application

public class IteratorDemo {
	public static void main(String[] args) {
		List<String> a = new ArrayList<>();
		a.add("jack");// ..
		// Get iterator
		Iterator Itr = a.iterator();
		while (Itr.hasNext()) {
			System.out.println(Itr.next());
		}
	}
}


The ArrayList aggregation implementation class implements the aggregation interface List

public interface List<E> extends Collection<E> {
    Iterator<E> iterator();
}

The internal class Itr implements the Iterator interface, which is a specific interface implementation class.

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
public Iterator<E> iterator() {
        return new Itr();
    }

    /**
     * An optimized version of AbstractList.Itr
     */
    private class Itr implements Iterator<E> {
        int cursor;       // index of next element to return
        int lastRet = -1; // index of last element returned; -1 if no such
        int expectedModCount = modCount;

        public boolean hasNext() {
            return cursor != size;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
}
  • The inner class Itr serves as the class that implements Iterator concretely and as the inner class of ArrayList
  • List acts as an aggregation interface and contains an iterator() method that returns an iterator object
  • ArrayList is a subclass that implements the aggregation interface List and implements iterator()
  • Provided by Iterator interface system
  • The iterator pattern solves the problem of uniform traversal of different sets (ArrayList, LinkedList)

summary

advantage

  • Provide a unified method to traverse objects. Customers can traverse objects with one method without considering the type of aggregation
  • The internal structure of the aggregation is hidden. When the client wants to traverse the aggregation, it can only get the iterator without knowing the specific composition of the aggregation
  • It provides a design idea that a class should have only one reason for change (called the single responsibility principle). In the aggregation class, we separate iterators to separate the responsibility of managing the object set and traversing the object set. In this way, if the set changes, it will only affect the aggregation object. If the traversal mode changes, it only affects the iterator.
  • When you want to show a group of similar objects or traverse a group of the same objects, it is suitable to use the iterator pattern

shortcoming

  • Each aggregate object needs - an iterator, which will generate multiple iterators, which is difficult to manage