Iterator pattern in Java

Introduction

Introducing the design patterns of [GoF](https://ja.wikipedia.org/wiki/Gang of for _ (Information Engineering)) ["Introduction to Design Patterns Learned in the Augmented and Revised Java Language"]( https://www.amazon.co.jp/ Supplementary Revised Edition Introduction to Design Patterns Learned in Java Language-Hiroshi Yuki / dp / 4797327030 / ref = pd_lpo_sbs_14_t_0? _ Encoding = UTF8 & psc = 1 & refRID = 2ZE4GPYNN55JGDR5QMHP I will summarize about.

Iterator pattern

What is Iterator

Iterator is an English word that means "** iterator " in Japanese. Especially in programming, it means an abstraction and generalization of " pointing things **" when accessing aggregates in sequence. I think it is difficult to grasp the image from this explanation alone, so I will give a more concrete example. I think many people have written a repeating statement that displays all the elements of the array ʻarray` as shown below.

sample.java


for (int i = 0; i < array.length; i++) {
  System.out.println(array[i]);
}

Here, the variable ʻi becomes a subscript of the array ʻarray, and the elements of the array are accessed in sequence. In this way, the Iterator is "** repeatedly points to the whole and scans **".

Character

The Itarator pattern uses the classes and interfaces that appear in the class diagram below. image.png

interface

Aggregate.java


public interface Aggregate {
	public abstract Iterator iterator();
}

Iterator.java


public interface Iterator {
	public abstract boolean hasNext();

	public abstract Object next();
}

Implementation class

Implement the interface and describe the specific processing. Specific examples will be described later.

Concrete example

As a concrete example, the explanation is based on "** Employee list that summarizes employees " and " Employee list Iterator **".

Implementation class

-** Employee class ** The Employee class represents an element of an aggregate. Have a name and employee code.

Employee.java


public class Employee {
	private String name;
	private String employeeCode;

	public Employee(String name, String employeeCode) {
		this.name = name;
		this.employeeCode = employeeCode;
	}

	public String getName() {
		return name;
	}

	public String getEmployeeCode() {
		return employeeCode;
	}
}

-** EmployeeList class ** The EmployeeList class represents a collection of employees. It has an array of employees and subscripts. ʻEmployeeListIterator is generated and returned with itself as an argument in ʻiterator ().

EmployeeList.java


public class EmployeeList implements Aggregate {
	private Employee[] employees;
	private int last = 0;

	public EmployeeList(int maxsize) {
		this.employees = new Employee[maxsize];
	}

	public Employee getEmployeeAt(int index) {
		return employees[index];
	}

	public void appendEmployee(Employee employee) {
		this.employees[last] = employee;
		last++;
	}

	public int getLength() {
		return last;
	}

	public Iterator iterator() {
		return new EmployeeListIterator(this);
	}
}

-** EmployeeListIterator class ** The EmployeeListIterator class represents an enumeration of a collection of employees. Have an employee list and subscripts. hasNext () checks if the employee list has the next element, and next () returns the next element (employee) of the employee list. There are various ways to access in sequence, but this time we will simply implement access in order from ** before **.

EmployeeListIterator.java


public class EmployeeListIterator implements Iterator {
	private EmployeeList employeeList;
	private int index;

	public EmployeeListIterator(EmployeeList employeeList) {
		this.employeeList = employeeList;
		this.index = 0;
	}

	public boolean hasNext() {
		if (index < employeeList.getLength()) {
			return true;
		} else {
			return false;
		}
	}

	public Object next() {
		Employee employee = employeeList.getEmployeeAt(index);
		index++;
		return employee;
	}
}

Execution class

-** Main class ** Employees are added to the employee list, and the name and employee code of the added employee are output from the employee list.

Main.java


public class Main {
	public static void main(String[] args) {
		EmployeeList employeeList = new EmployeeList(4);
		employeeList.appendEmployee(new Employee("Tarou_Tanaka", "C001"));
		employeeList.appendEmployee(new Employee("Hanako_Yamada", "C002"));
		employeeList.appendEmployee(new Employee("Yuuya_Suzuki", "C003"));
		employeeList.appendEmployee(new Employee("Kanako_Satou", "C004"));
		Iterator it = employeeList.iterator();
		while (it.hasNext()) {
			Employee employee = (Employee) it.next();
			System.out.println(employee.getName() + ":" + employee.getEmployeeCode());
		}
	}
}

Execution result

The result of executing Main.class is as follows. You can see that the output is correct in the order in which they were added to ʻemployeeList`.

Execution result


Tarou_Tanaka:C001
Hanako_Yamada:C002
Yuuya_Suzuki:C003
Kanako_Satou:C004

merit

By using Iterator, you don't have to be aware of what kind of set is (array, ArrayList, Vector, etc.) and what kind of implementation is done when counting. Below we define ʻEmployeeList.classwhich changed the aggregate from an array to an ArrayList. At this time, there is no need to modify the execution classMain.class`, and the execution result is the same as for an array.

EmployeeList.java


import java.util.ArrayList;

public class EmployeeList implements Aggregate {
	private ArrayList<Employee> employees;

	public EmployeeList(int initialsize) {
		this.employees = new ArrayList<>(initialsize);
	}

	public Employee getEmployeeAt(int index) {
		return (Employee) employees.get(index);
	}

	public void appendEmployee(Employee employee) {
		employees.add(employee);
	}

	public int getLength() {
		return employees.size();
	}

	public Iterator iterator() {
		return new EmployeeListIterator(this);
	}
}

Execution result


Tarou_Tanaka:C001
Hanako_Yamada:C002
Yuuya_Suzuki:C003
Kanako_Satou:C004

Postscript (2018/10/31)

There are various ways to access Iterator other than accessing it sequentially from the front. (Reverse order, skip one, etc.) This time, we have added Iterator to access in reverse order with ArrayList. Only the classes with differences will be posted, so for other classes, [Summary](https://qiita.com/mk777/items/398bd26de44eac4f383b#%E3%81%BE%E3%81%A8%E3%82% Please check with 81).

interface

Aggregate.class


public interface Aggregate {
	public abstract Iterator iterator();

	public abstract Iterator reverseIterator();
}

Implementation class

-** EmployeeList class ** We are adding reverseIterator (). In reverseIterator (), ʻEmployeeListReverseIterator` is generated and returned with itself as an argument.

EmployeeList.class


import java.util.ArrayList;

public class EmployeeList implements Aggregate {
	private ArrayList<Employee> employees;

	public EmployeeList(int initialsize) {
		this.employees = new ArrayList<>(initialsize);
	}

	public Employee getEmployeeAt(int index) {
		return (Employee) employees.get(index);
	}

	public void appendEmployee(Employee employee) {
		employees.add(employee);
	}

	public int getLength() {
		return employees.size();
	}

	public Iterator iterator() {
		return new EmployeeListIterator(this);
	}

	public Iterator reverseIterator() {
		return new EmployeeListReverseIterator(this);
	}
}

-** EmployeeListReverseIterator class ** Although it is a newly created class, it implements hasNext () and next () in the same way as ʻEmployeeListIterator.class that accesses sequentially. The constructor has the number of elements in ʻemployeeList minus 1 in ʻindex. As a result, 4 will be obtained from the list with 5 elements. In hasNext (), access is performed in reverse order as many as the number of elements in ArrayList. It should be noted that ** the loop condition must ensure that ʻindex is not less than 0 **. Without this condition, next () will try to access employeeList [-1] and ʻArrayIndexOutOfBoundsException` will occur.

EmployeeListReverseIterator.class


public class EmployeeListReverseIterator implements Iterator {
	private EmployeeList employeeList;
	private int index;

	public EmployeeListReverseIterator(EmployeeList employeeList) {
		this.employeeList = employeeList;
		this.index = employeeList.getLength() - 1;
	}

	public boolean hasNext() {
		if (index < employeeList.getLength() && index >= 0) {
			return true;
		} else {
			return false;
		}
	}

	public Object next() {
		Employee employee = employeeList.getEmployeeAt(index);
		index--;
		return employee;
	}
}

Execution class

-** Main class ** After adding ʻEmployee to ʻEmployee List and outputting in sequence, output is done in reverse order.

Main.class


public class Main {
	public static void main(String[] args) {
		EmployeeList employeeList = new EmployeeList(4);
		employeeList.appendEmployee(new Employee("Tarou_Tanaka", "C001"));
		employeeList.appendEmployee(new Employee("Hanako_Yamada", "C002"));
		employeeList.appendEmployee(new Employee("Yuuya_Suzuki", "C003"));
		employeeList.appendEmployee(new Employee("Kanako_Satou", "C004"));
		Iterator it = employeeList.iterator();
		System.out.println("------- Order -------");
		while (it.hasNext()) {
			Employee employee = (Employee) it.next();
			System.out.println(employee.getName() + ":" + employee.getEmployeeCode());
		}
		System.out.println("------- Reverse Order -------");
		Iterator rit = employeeList.reverseIterator();
		while (rit.hasNext()) {
			Employee employee = (Employee) rit.next();
			System.out.println(employee.getName() + ":" + employee.getEmployeeCode());
		}
	}
}

Execution result

The result of executing Main.class is as follows. You can see that the output is in the order ** added to ʻemployeeList` and ** reverse order ** with the added ones.

Execution result


------- Order -------
Tarou_Tanaka:C001
Hanako_Yamada:C002
Yuuya_Suzuki:C003
Kanako_Satou:C004
------- Reverse Order -------
Kanako_Satou:C004
Yuuya_Suzuki:C003
Hanako_Yamada:C002
Tarou_Tanaka:C001

Summary

You learned about the Iterator pattern, which accesses aggregates in sequence. The sample code is uploaded below, so please refer to it if you like.

-Iterator sample code

In addition, other design patterns are summarized below, so please refer to them as well.

-[Updated from time to time] Summary of design patterns in Java

References

-[Introduction to Design Patterns Learned in the Augmented and Revised Java Language](https://www.amazon.co.jp/ Introduction to Design Patterns Learned in the Augmented and Revised Java Language-Hiroshi Yuki / dp / 4797327030 / ref = pd_lpo_sbs_14_t_0? _Encoding = UTF8 & psc = 1 & refRID = 2ZE4GPYNN55JGDR5QMHP)

Recommended Posts

Iterator pattern in Java
Singleton pattern in Java
Flyweight pattern in Java
Observer pattern in Java
Decorator pattern in Java
Prototype pattern in Java
Proxy pattern in Java
Template Method pattern in Java
Chain of Responsibility pattern in Java
Iterator in MySQLdb
Learn the design pattern "Iterator" in Python
Singleton pattern in Python
Linux permissions in Java
Use DataFrame in Java
Visitor pattern in Python
I wrote a design pattern in kotlin, Iterator edition
Implement Table Driven Test in Java
Detect and process signals in Java.
Implement the Singleton pattern in Python
5-1, iterator
Split iterator into chunks in python
Implemented bubble sort in Java (BubbleSort)
GoF java design pattern rough summary
Overlapping regular expressions in Python and Java
Learn the design pattern "Prototype" in Python
Learn the design pattern "Flyweight" in Python
Learn the design pattern "Memento" in Python
Learn the design pattern "Proxy" in Python
Express Python yield in JavaScript or Java
Apply Google Java Style formatter in IntelliJ
Learn the design pattern "Command" in Python
[Gang of Four] Design pattern learning --Iterator
Differences in syntax between Python and Java
Get mail using Gmail API in Java
Learn the design pattern "Visitor" in Python
Learn the design pattern "Bridge" in Python
Learn the design pattern "Mediator" in Python
Learn the design pattern "Decorator" in Python
Learn the design pattern "Strategy" in Python
Learn the design pattern "Composite" in Python
Learn the design pattern "State" in Python
Let's run a Bash script in Java
Learn the design pattern "Adapter" in Python