Location>code7788 >text

Design Patterns - Iterator Pattern

Popularity:499 ℃/2024-08-31 16:54:59

The Iterator pattern is familiar to many, but what is an iterator and why do you need one?
This many people will be difficult to make a specific answer, just know that if there is an iterator, then we can foreach traversal, convenient loop processing.
This is just an answer to what iterators are used for, the foreach syntax is a syntactic sugar that was added with java 1.5, so what about before that, what was done before that?
You know that not all containers support the index position of the form, to get a specific location of the element, so for this unordered container then how to traverse it?
This brings us to the iterator pattern
The iterator pattern means that you don't need to know the details of the container's internal data storage in order to fetch the elements of the container in some order.
Whereas in java, the default interfaces are already open, and you just need to implement the corresponding methods according to the conventions of the interfaces:
The class diagram is shown below:

 

We write a copy of the implementation code as required, and unlike previous containers, the data is stored in only one copy, but I can traverse a number of copies of each copy of the data when we require traversal:

Container classes, iterator classes

 1 package ;
 2 
 3 import ;
 4 
 5 /**
 6  * @discription
 7  */
 8 public class FixCollection<T> implements Iterable<T> {
 9     Object[] data;
10 
11     int max;
12 
13     int cur = 0;
14 
15     int loop = 0;
16 
17     public FixCollection(int max, int loop) {
18         this.max = max;
19         data = new Object[max];
20         this.loop = loop;
21     }
22 
23     public boolean addData(T t) {
24         if (cur < max) {
25             data[cur++] = t;
26             return true;
27         }
28         return false;
29     }
30 
31 
32     @Override
33     public Iterator<T> iterator() {
34         return new LoopIterator();
35     }
36 
37     class LoopIterator implements Iterator<T> {
38         // Index location.
39         int index = 0;
40 
41 
42         public LoopIterator() {
43         }
44 
45         public boolean hasNext() {
46             return cur * loop >= (index + 1);
47         }
48 
49         public T next() {
50             int i = index++ % cur;
51             return (T) data[i];
52         }
53     }
54 }

main category

 1 package ;
 2 
 3 import .slf4j.Slf4j;
 4 
 5 import ;
 6 
 7 /**
 8  * @discription
 9  */
10 
11 @Slf4j
12 public class IterMain {
13     public static void main(String[] args) {
14         FixCollection<String> collection = new FixCollection(4, 3);
15         ("1a");
16         ("2a");
17         ("3a");
18         ("4a");
19         ("5a");
20         Iterator<String> iter = ();
21         int i = 0;
22         while (()) {
23             ("iter element is {}:{}", i++, ());
24         }
25 
26         int j = 0;
27         for (String item : collection) {
28             ("for element is {}:{}", j++, item);
29         }
30     }
31 }

 

The result of the call is as follows:

16:51:57.870 [main] WARN  - iter element is 0:1a
16:51:57.873 [main] WARN  - iter element is 1:2a
16:51:57.873 [main] WARN  - iter element is 2:3a
16:51:57.873 [main] WARN  - iter element is 3:4a
16:51:57.873 [main] WARN  - iter element is 4:1a
16:51:57.873 [main] WARN  - iter element is 5:2a
16:51:57.873 [main] WARN  - iter element is 6:3a
16:51:57.873 [main] WARN  - iter element is 7:4a
16:51:57.873 [main] WARN  - iter element is 8:1a
16:51:57.873 [main] WARN  - iter element is 9:2a
16:51:57.873 [main] WARN  - iter element is 10:3a
16:51:57.873 [main] WARN  - iter element is 11:4a
16:51:57.873 [main] WARN  - for element is 0:1a
16:51:57.873 [main] WARN  - for element is 1:2a
16:51:57.873 [main] WARN  - for element is 2:3a
16:51:57.873 [main] WARN  - for element is 3:4a
16:51:57.873 [main] WARN  - for element is 4:1a
16:51:57.873 [main] WARN  - for element is 5:2a
16:51:57.873 [main] WARN  - for element is 6:3a
16:51:57.873 [main] WARN  - for element is 7:4a
16:51:57.873 [main] WARN  - for element is 8:1a
16:51:57.874 [main] WARN  - for element is 9:2a
16:51:57.874 [main] WARN  - for element is 10:3a
16:51:57.874 [main] WARN  - for element is 11:4a

The main steps are this:

1. Our custom container, which implements the Iterable interface, indicates that the custom container supports returning an iterator.
2, we return an iterator that implements the Iterator interface and supports the basic methods of an iterator (and whether there is a next element hasNext(), and return the next element next()).

This way we can use iterators, or we can use foreach syntactic sugar to traverse as in the example, with the compiler doing the relatively obscure transcription for me.
At this point someone asked, this iterator pattern is a bit too rigid, my container class directly supports the return of the object in turn, is still considered an iterator pattern?
The answer is that it counts, as long as your container doesn't expose specific data and supports returning data elements sequentially, it's considered an iterator pattern. It's just that you're now combining the functionality of containers and iterators into one, and containers have to maintain the state of access from the outside world, which is relatively less elegant than the official convention.
Don't think of design patterns as overly complex and stereotypical. In fact, we are already using a variety of design patterns, consciously or unconsciously, when dealing with problems according to object-oriented principles.