Iterator mode
The iterator pattern, also called the cursor pattern, provides a way to access individual objects in a container element without exposing the object's internal details .
Iterator pattern structure
The iterator pattern consists of the following roles:
1. Iterator role
Interface for defining access and traversal elements
2. Specific iterator role
Implement the iterator interface and record the current position in the traversal
3. Container role
Responsible for providing an interface for creating specific iterator roles
4. Specific container roles
Implements an interface that creates a specific iterator role that is related to the structure of the container
Application and interpretation of iterator pattern in JDK
The iterator pattern does not write itself as an example, directly using the examples in the JDK. Why do we use the iterator pattern to think about a problem if I have a ArrayList and a linkedlist:
New Arraylist<integer>(); Arraylist.add (1); Arraylist.add (2) ; ListNew linkedlist<integer>(); Linkedlist.add (3); Linkedlist.add (4);
How to traverse these two lists believe that everyone knows:
System.out.println ("ArrayList:"); for (int i = 0; i < arraylist.size (); i++) + "\ T"); System.out.println ("\nlinkedlist:"); for (int i = 0; i < linkedlist.size (); i++) + "\ T");
The result of the operation is:
ArrayList:1 2 linkedlist:3 4
This is because just as we know the way ArrayList and LinkedList are accessed, some people who like to study know the internal structure of ArrayList and LinkedList, but if I give you a hashset now:
New Hashset<integer>(); Hashset.add (5); Hashset.add (6);
How will it be traversed? Maybe you thought you could use a list-like traversal, but unfortunately there is no get method available in HashSet.
This is the turn of the iteration, no matter what data structure, whether you have heard or have not heard, whether you have seen or not seen, as long as it implements the Iterable interface, can be used in a similar way to traverse, I put ArrayList, LinkedList, The traversal of the HashSet is written together:
Iterator<integer> iter =NULL; System.out.println ("ArrayList:"); ITER=arraylist.iterator (); while(Iter.hasnext ()) {System.out.print (Iter.next () )+ "\ T");} System.out.println ("\nlinkedlist:"); ITER=linkedlist.iterator (); while(Iter.hasnext ()) {System.out.print (Iter.next () )+ "\ T");} System.out.println ("\nhashset:"); ITER=hashset.iterator (); while(Iter.hasnext ()) {System.out.print (Iter.next () )+ "\ T");}
Look at the results of the operation:
ArrayList:1 2 linkedlist:3 4 HashSet:5 6
See this is traversed out ArrayList, LinkedList, HashSet, and later encountered a set, as long as the implementation of the Iterable interface, can also be similar to the traversal. This is what the definition of the beginning iterator pattern says, and the developer doesn't need to know the details of how the collection is going to be traversed, just use a similar traversal method.
Iterable interface and Iterator interface
These two are iterative related interfaces, so to think that the implementation of the Iterable interface, it means that an object can be iterated, the iterator interface is equivalent to an iterator, the implementation of the iterator interface, equal to the specific definition of the object can be iterated how to iterate. See definition of Iterable interface:
Public Interface Iterable<t> { /** * Returns An iterator over a set of elements of type T. * @return an Iterator. */ Iterator<T> Iterator ();}
This allows the object to iterate using iterators of this class, and the general iterable and iterator interfaces are used together. Why must realize the Iterable interface and not directly implement the iterator interface, this problem I also wrote ArrayList and LinkedList realized after I want to understand, so do have a reason:
Because the core method of the Iterator interface next () or Hasnext () is dependent on the current iteration position of the iterator. If collection implements the iterator interface directly, it is bound to cause the collection object to contain the data of the current iteration position, when the collection is passed between different methods, because the current iteration position cannot be preset, the result of the next () method becomes unpredictable. Unless you add a reset () method to the iterator interface, you can reset the current iteration position. But even so, collection can only have one current iteration position at a time. Instead of iterable, each call returns an iterator that counts from the beginning, and multiple iterators do not interfere with each other.
Perhaps this explanation is not very clear, and then explained that I wrote a ArrayList, if the direct implementation of the iterator interface, then it is bound to write:
Public classArraylist<e>ImplementsList<e>, iterator<e>, Randomaccess, cloneable, serializable{/*** Serialization ID*/ Private Static Final LongSerialversionuid = -5786598508477165970l; Private intSize = 0; Private transientobject[] Elementdata =NULL; PublicE Next () {... } Public BooleanHasnext () {... } ...}
So the question is, if a ArrayList instance is iterated by multiple places, the next () method, Hasnext () is directly manipulating the resources in ArrayList, and if I define a variable in the ArrayList for an iteration position, then for different calls, This iteration variable is shared, the iteration variable is set to the 5th position when thread A iterates, this time switch to thread B, for thread B, it starts from the 5th position to traverse this ArrayList, is not starting from 0, how to correctly iterate?
Implementing the Iterable interface returning an instance of an iterator interface is different, I define an inner class for the ArrayList I write:
Public classArraylistiteratorImplementsIterator<e>{ intiteratorpostion = 0; /*** Determine if there are elements behind*/@Override Public BooleanHasnext () {if((iteratorpostion + 1) >size)return false; return true; } /*** Returns a reference to a previous element*/@Override PublicE Next () {return(E) elementdata[iteratorpostion++]; } ...}
Returns a Arraylistiterator instance each time it goes out:
/*** /public iterator<e> Iterator () {returnNew arraylistiterator ();}
This ensures that even when multiple iterations of the ArrayList are in place, each of these ArrayList instances is iterated from 0.
Advantages and disadvantages of the iterator pattern
Advantages
1, simplifying the convenient way, for the object collection of traversal, or more troublesome, for arrays or have a sequence of tables, we can also be obtained by subscript, but users need to know the set very well, in order to traverse the object (sometimes even if you know the collection, it may not be able to traverse directly, For example, the hashset above does not provide a Get method). With the introduction of the iterator method, the user is simply a lot easier to use.
2, can be used for a variety of traversal methods, for example, there is a sequence of tables, can be forward traversal can also be reversed, as long as the iterator implementation is good
3, the package is good, the user only need to get the iterator can traverse, but for the traversal algorithm does not need to care
Disadvantages
For relatively simple traversal (arrays or sequential tables), using iterators to traverse a cumbersome and inefficient traversal, using iterators in a way that is more suitable for the underlying list-based implementation of the collection
Java design mode 8: Iterator mode