What is an iterator?
Iterators (Iterator) are a mechanism by which elements in one or more containers are traversed in a certain order, such as a For loop is the simplest iterator, and the traversal of an array is also a process of iterative traversal. GOF provides a way to access individual elements of a container (container) object without exposing the object's internal details. Iterators are sometimes called enumerators (enumerator), and their structure is as follows:
Iterator structure diagram
The iterator actually maintains a current pointer, which can point to the current element, can return the currently pointed element, and can be moved to the position of the next element, through which all elements of the container can be traversed. Iterators generally have at least the following methods:
First (); Move the pointer to the first position or get the first element
GetCurrent (); Gets the element that is currently pointing
MoveNext (); Move to the next element
How to use iterators
Since iterators are the implementation details inside the package, providing an interface for easy access to the container elements, let's first understand the iterators from the perspective of usage and see how iterators are used in various languages.
Iterators in C + +:
void Testiterator () {vector<int> vec;//defines a container for (int i = 0; i < 5; i++) {vec.push_back (i*2);//Add Element}// Use iterators to access each element in the container cout << "iterator vector:" << endl;for (vector<int>::iterator ITR = Vec.begin (); ITR! = Vec.end (); ITR + +) {cout << *itr << " ";//itr is a pointer to the current element, so you want to dereference the element value}cout << Endl;map<int, string> student;//Create a map, corresponding to the number-name of the key value pair//Add element Student.insert (Pair<int, string> (1, "Zhang San")); Student.insert (Pair<int, String> (3, "Harry")); Student.insert (Pair<int, string> (2, "John Doe"));//traversal of elements in a container cout << "iterator map:" < < Endl;for (Map<int, String>::iterator ITR = Student.begin (); ITR! = Student.end (); ITR + +) {cout << Itr-> ; first << "--" << itr->second << Endl;}}
Results:
Iterator vector:
0 2 4) 6 8
Iterator map:
1--> Zhang San
2--> John Doe
3--> Harry
Containers in C + +, such as vectors, map, list, set, and so on, typically provide four iterators:
Iterator: Forward iteration, traversing backward, modifying the value of an element
Const_iterator: A forward constant iteration, but cannot modify the value of an element because it points to a const reference
Reverse_iterator: Reverse iteration, traversing backwards, modifying the value of an element
Const_reverse_iterator: Inverse constant iteration, but cannot modify the value of the element because it points to a const reference
Each iterator provides a one-to-the-end flag beginning and ending, with the following relationships:
iterator type |
start position flag |
end position flag |
description |
Iterator |
Begin () |
End () |
Forward Iteration |
Const_iterator |
Cbegin () |
Cend () |
Forward constant Iteration |
Reverse_iterator |
Rbegin () |
Rend () |
Reverse Iteration |
Const_reverse_iterator |
Crbegin () |
Crend () |
Inverse constant Iteration |
Corresponds to the following:
Figure 1: a normal iteration
Figure 2: Iteration of a constant value
Iterators in Java:
public static void Testiterator () {//Creates a list list<integer> lists = new arraylist<integer> (); List.add (4);// add element List.add (3); List.add (7);//Returns an iterator and iterates over the elements in the list iterator<integer> iterator = List.iterator (); while ( Iterator.hasnext ()) {Integer value = Iterator.next (); System.out.print (value + " ");} System.out.println ();//returns the Listiterator iterator and iterates forward from the list element listiterator<integer> Listiterator = List.listiterator ( List.size ()); System.out.println ("Listiterator:"); while (Listiterator.hasprevious ()) {Integer value = listiterator.previous (); System.out.print (value + " ");} System.out.println ();}
Results:
Iterator begin to end:
4 3 7
Listiterator End to begin:
7 3 4
The list interface and its implementation classes in Java can be returned iterator via iterator (), or Listiterator by Listiterator () and listiterator (int index).
Iterator and Listiterator are iterators, listiterator inherit from iterator. Iterator can only traverse the list, and traverse only from the back, Listiterator may modify the list, and can choose to traverse forward or backward. For more detailed instructions on Iterator and Listiterator see the Official API:Iterator and listiterator
Iterators in JavaScript
JavaScript indicates that the container is of type array, the standard does not give the description and implementation of the corresponding iterator, but we can implement a simple iterator function:
<script type= "Text/javascript" >//creates an iterator that must pass in the array type data function Makeiterator (array) {var index = 0;return { Hasnext:function () {return index < Array.length;},next:function () {return this.hasnext? array[index++]: NULL;},CU Rrent:function () {return array[index];}};} Create an array and assign a value var mycars=new array (); mycars[0]= "Saab"; mycars[1]= "Volvo"; mycars[2]= "BMW";//Create an iterator for the array mycars, and iterate through the data element var iterator = Makeiterator (Mycars), while (Iterator.hasnext ()) {document.write (Iterator.next () + ' <br > ');} </script>
Results:
Saab
Volvo
BMW
The JavaScript 1.7 provided by Mozilla has added the functionality of an iterator, but it is now only available in the Firefox browser. Such as:
<script type= "application/javascript;version=1.7" >var lang = {name: ' JavaScript ', birthyear:1995, age:19}; Generate an iterator var itr = Iterator (lang);d ocument.write (' key-value: ' + ' <br> '); for (var key in ITR) {document.write (key + ') <br> ');} This iterator iterates through each of the key values var itr2 = Iterator (lang, false);d Ocument.write (' key: ' + ' <br> '); for (var key in itr2) { document.write (key + ' <br> ');} This iterator iterates through each index and value var arrs = [' JavaScript ', ' Python ', ' Haskell '];var itr3 = Iterator (Arrs, False);d Ocument.write (' Index-value: ' + ' <br> '); for (let [I, value] in ITR3) {document.write (i + ': ' + value + ' <br> ');} </script>
Results:
Key-value:
Name,javascript
birthyear,1995
age,19
Key
Name,javascript
birthyear,1995
age,19
Index-value:
0:javascript
1:python
2:haskell
For more iterators on JavaScript 1.7 see:iterators and generators
Advanced Applications for Iterators
In the previous section, "Iterators in JavaScript," you have implemented an iterator of your own definition for array arrays. The iterators described above are basically the same data types as the elements inside the collection, but there may be more complex container structures in the actual development process, assuming the following need:
A company has multiple departments, each with a number of people, such as developers, testers, and other personnel associated with the project, with the following structure:
Now traverse all the developers in the company and traverse all the testers in the company.
For this requirement, we can create a custom iterator to traverse a company's staff, or pass in an employee type to traverse a specified type of employee whose class structure is as follows:
The corresponding implementation code is as follows:
[email protected]: Luoweifu/iteratortest.git
The corresponding calling code is as follows:
#include "stdafx.h" #include <string> #include <iostream> #include "Person.h" #include "Department.h" # Include "Company.h" #include "Enumerator.h" int _tmain (int argc, _tchar* argv[]) {Company Company ("Apabi");D epartment* PDepartMent1 = new Department ("Development 1");D epartment* pDepartMent2 = new Department ("Development 2");D epartment* pDepartMent3 = new De Partment ("Core Development department"); Adddepartment (pDepartMent1); company. Adddepartment (PDepartMent2); company. Adddepartment (PDEPARTMENT3); int empId = 1; person* pPerson11 = new Developer (empid++, "Developer11", "C + +", "smart city"); person* pPerson12 = new Developer (empid++, "Developer12", "Java", "smart city"); person* pPerson13 = new Developer (empid++, "Developer13", "Java", "smart city"); person* pPerson14 = new Developer (empid++, "Developer14", "JavaScript", "smart city"); person* pPerson15 = new Tester (empid++, "Tester15", "LoadRunner"); person* PPerson16 = new Tester (empid++, "Tester16", "black Box Test"), cout << pperson16->getpersontype () << Endl; Pdepartment1->addperson (PPERSON11);pD Epartment1->addperson (pPerson12);pD Epartment1->addperson (pPerson13);pD epartment1-> Addperson (PPERSON14);pD Epartment1->addperson (pPerson15);pD Epartment1->addperson (PPerson16); person* pPerson21 = new Developer (empid++, "Developer21", "IOS", "Mobile"); person* pPerson22 = new Developer (empid++, "Developer22", "Android", "Mobile"); person* pPerson23 = new Tester (empid++, "Tester23", "LoadRunner"); person* PPerson24 = new Tester (empid++, "Tester24", "Testin");pD Epartment2->addperson (pPerson21);pD epartment2- >addperson (pPerson22);pD Epartment2->addperson (pPerson23);pD Epartment2->addperson (PPERSON24); person* pPerson31 = new Developer (empid++, "Developer31", "C + +", "cebx kernel"); person* pPerson32 = new Developer (empid++, "Developer32", "C + +", "cebx kernel"); person* pPerson33 = new Developer (empid++, "Developer33", "C + +", "cebx kernel"); person* pPerson34 = new Developer (empid++, "Developer34", "C + +", "cebx kernel"); person* pPerson35 = new Tester (empid++, "Tester35", "LoadRunner");Pdepartment3->addperson (PPERSON31);pD Epartment3->addperson (pPerson32);pD Epartment3->addperson ( PPERSON33);pD Epartment3->addperson (pPerson34);pD Epartment3->addperson (pPerson35);//Traverse All developers cout << " Traverse all developers: "<< Endl; enumerator* PEnumerator1 = Company. GetEnumerator (Person_developer); while (Penumerator1->movenext ()) {person* Pperson = penumerator1->current (); if (Pperson) {pperson->showinfo ();}} Delete penumerator1;//traverse all testers cout << "traverse all Testers:" << Endl; enumerator* PEnumerator2 = Company. GetEnumerator (Person_tester); while (Penumerator2->movenext ()) {person* Pperson = penumerator2->current (); if ( Pperson) {pperson->showinfo ();}} Delete penumerator2;//Traverse Company All employees cout << "traverse Company All Employees:" << Endl; enumerator* PEnumerator3 = Company. GetEnumerator (Person_type_none); while (Penumerator3->movenext ()) {person* Pperson = penumerator3->current (); if (Pperson) {pperson->showinfo ();}} Delete Penumerator3;return 0;}
This makes the code simple, easy to read.
Application Scenarios for iterators
1. The internal structure of the collection is complex and does not want to expose the internal details of the object, only provides a streamlined access mode;
2. You need to provide a unified access interface to use the same algorithm for different collections.
programming Thought series review =====================
The recursion of programming thought
The callback of programming thought
An iterative device for programming ideas