Writing in the front

  • Take notes on learning design patterns
  • Improve the flexible use of design patterns

Learning to address



Refer to the article


Project source https://gitee.com/zhuang-kang/DesignPattern

20. Iterator pattern

20.1 Definition and characteristics of the iterator pattern

Definition of the Iterator pattern: An object is provided to access a sequence of data in an aggregate object without exposing the internal representation of the aggregate object. The iterator pattern is an object behavior pattern with the following major benefits.

  1. Access the contents of an aggregate object without exposing its internal representation.
  2. The task of traversal is left to iterators, which simplifies the aggregation class.
  3. It allows you to iterate over an aggregate in different ways, and you can even subclass iterators to support new iterations.
  4. It’s easy to add new aggregator and iterator classes without changing the original code.
  5. Good encapsulation, providing a unified interface for traversing different aggregation structures.

Its main disadvantages are:

  • The number of classes is increased, which increases the complexity of the system to some extent.

The structure and implementation of the iterator pattern

20.2.1 Structure of the iterator pattern

  1. The Aggregate role: Defines interfaces to store, add, and delete Aggregate objects, and create iterator objects.
  2. ConcreteAggregate role: Implements an abstract aggregate class that returns an instance of a concrete iterator.
  3. The abstract Iterator role: Defines an interface to access and iterate over an aggregated element, typically including methods hasNext(), first(), next(), and so on.
  4. Concretelterator: Implements methods defined in the abstract iterator interface to complete traversal of aggregate objects and record the current location of traversal.

20.2.2 Code implementation

Define a container object that can store student objects, leaving iterators to iterate over the container

Relationship between the class diagram


package com.zhuang.Iterator; /** * @className Student * @description Student * @date 2021/3/28 12:47 * @created by dell */ public class Student {private  String name; private String number; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public Student() { } public Student(String name, String number) { this.name = name; this.number = number; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", number='" + number + '\'' + '}'; }}


package com.zhuang.Iterator; /** * @ClassName StudentIterator * @Description Iterator interface * @Date 2021/3/28 12:43 * @Created by Dell */ public interface StudentIterator { boolean hasNext(); Student next(); }


package com.zhuang.Iterator; import java.util.List; /** * @ClassName StudentIteratorImpl * @description Specifies an iterator class * @date 2021/3/28 12:43 * @created by Dell */ public class StudentIteratorImpl implements StudentIterator { private List<Student> list; private int position = 0; public StudentIteratorImpl(List<Student> list) { this.list = list; } @Override public boolean hasNext() { return position < list.size(); } @Override public Student next() { Student currentStudent = list.get(position); position++; return currentStudent; }}


package com.zhuang.Iterator; /** * @ClassName StudentAggregate * @Description Abstract container class * @Date 2021/3/28 12:44 * @created by Dell */ Public interface StudentAggregate {// addStudent function void addStudent(Student Student); Void removeStudent(Student Student); // Get the iterator function object StudentIterator getStudentIterator(); }


package com.zhuang.Iterator; import java.util.ArrayList; import java.util.List; /** * @ClassName StudentAggregateImpl * @Description Specific container class * @Date 2021/3/28 12:44 * @created by dell */ public class StudentAggregateImpl implements StudentAggregate { private List<Student> list = new ArrayList<Student>(); @Override public void addStudent(Student student) { this.list.add(student); } @Override public void removeStudent(Student student) { this.list.remove(student); } @Override public StudentIterator getStudentIterator() { return new StudentIteratorImpl(list); }}


package com.zhuang.Iterator; /** * @className Client * @description * @date 2021/3/28 12:54 * @created by dell */ public class Client { public static void main(String[] args) { StudentAggregateImpl aggregate = new StudentAggregateImpl(); // Add element aggregate. AddStudent (new Student(" three ", "001")); Aggregate. AddStudent (new Student(" 0 ", "002")); Aggregate. AddStudent (new Student(" 5 ", "003")); Aggregate. AddStudent (new Student(" zhao 6 ", "004")); Aggregate. AddStudent (new Student(" 0 ", "0 ")); / / traverse the aggregate object StudentIterator iterator. = aggregate getStudentIterator (); While (iterator.hasnext ()) {Student Student = iterator.next(); System.out.println(student); }}}

20.3 Application scenarios of the iterator pattern

  • When you need to provide multiple traversal methods for an aggregate object.
  • When you need to provide a unified interface for traversing different aggregate structures.
  • When accessing the contents of an aggregate object without exposing its internal details.

20.4 JDK source parsing

The iterator pattern is widely used in many collections classes in JAVA. Let’s take a look at how the iterator pattern is used in the JAVA source code.

List<String> list = new ArrayList<>(); Iterator<String> iterator = list.iterator(); While (iterator.hasnext ()) {system.out.println (iterator.next()); }

If you are familiar with this code, it is basically similar to our code above. Single-column collections all use iterators, as illustrated by an ArrayList

  • List: abstract aggregate class
  • ArrayList: concrete aggregate class
  • Iterator: Abstract Iterator
  • List.iterator () : Returns the implementationIteratorA concrete iterator object for the interface

Take a look at the code implementation of ArrayList

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E> { int cursor; // The index of the next element to be returned int lastRet = -1; // The index of the last returned element int expectedModCount = modCount; Itr() {} public Boolean hasNext() {return cursor! = size; } 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]; }... }

This part of the code is still relatively simple. It basically returns an instantiated iterator object in the iterator method. The Itr is an inner class that implements the Iterator interface and overwrites its abstract methods.


When we want to use the iterator pattern in JAVA development, we simply have our own container class implement 'java.util.Iterable' and implement its iterator() method so that it returns an implementation class of 'java.util. iterator'.

Write in the last

  • If my article is useful to you, please give me a point 👍, thank you 😊!
  • Feel free to let us know in the comments! 💪