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 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 **".
The Itarator pattern uses the classes and interfaces that appear in the class diagram below.
Aggregate.java
public interface Aggregate {
public abstract Iterator iterator();
}
hasNext ()
and next ()
.
Use hasNext ()
to see if it has the following elements:
next ()
is used to get the next element when it is present.Iterator.java
public interface Iterator {
public abstract boolean hasNext();
public abstract Object next();
}
Implement the interface and describe the specific processing. Specific examples will be described later.
As a concrete example, the explanation is based on "** Employee list that summarizes employees " and " Employee list Iterator **".
-** 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;
}
}
-** 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());
}
}
}
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
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 class
Main.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
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).
reverseIterator ()
to generate an Iterator that accesses in reverse order.Aggregate.class
public interface Aggregate {
public abstract Iterator iterator();
public abstract Iterator reverseIterator();
}
-** 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;
}
}
-** 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());
}
}
}
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
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.
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
-[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