Overview of Java iterators

Source: Internet
Author: User
Tags iterable concurrentmodificationexception java iterable

I. Summary

The iterator pattern is associated with a collection of co-deaths. In general, we need to provide an iterator for this container as long as we implement a container. The advantage of using iterators is that you encapsulate the internal implementation details of the container, and for different collections, you can provide a unified way of traversing, simplifying client access and getting data inside the container. Based on this, we can use Iterator to complete the traversal of the collection, in addition, the For loop and the foreach syntax can also be used to traverse the collection class. Listiterator is a bidirectional iterator unique to the container list container family. The main points of this paper include:

    • Iterator mode
    • Iterator Iterators and Iterable interfaces
    • Cyclic traversal: Similarities and differences of foreach,iterator,for
    • Listiterator Brief (container List details)
Second, the iterator mode

  The iterator pattern is associated with a collection of co-deaths. in general, as long as we implement a container, we need to provide an iterator to the container, like Collection in Java (list, Set, etc.), which have their own iterators. If we are going to implement a new container, of course we need to introduce the iterator pattern and implement an iterator to our container. The advantage of using iterators is that you encapsulate the internal implementation details of the container, and for different collections, you can provide a unified way of traversing, simplifying client access and getting data inside the container.

However, because containers are too closely related to iterators, most languages implement containers while providing the appropriate iterators, and in the vast majority of cases, the containers and iterators provided by these languages can meet our needs. Therefore, the reality of the need for us to implement the iterator pattern of the scene is still relatively rare, we often only need to use the language of the existing containers and iterators can be.

1. Definition and structure

    • Defined

      Iterator (Iterator) mode, also known as cursor mode. Gof gives the definition of providing a way to access individual elements in a container (container) object without exposing the inner details of the container object.

      The iterator pattern is visible from the definition and is for the container. we know that access to the container object necessarily involves a traversal algorithm. You can plug the Traversal method into the container object in a single brain, or not provide any traversal algorithms at all, so that the person who uses the container realizes it on its own. Both of these situations seem to solve the problem. However, in the former case, the container is subjected to too much function, it is not only responsible for the elements of its own "container" maintenance (add, delete, change, check, etc.), but also to provide the interface to traverse itself, and most importantly, because of the problem of traversal state preservation, can not be multiple traversal of the same container object, And you need to increase the reset operation . The second approach is easy, but it exposes the inner details of the container.

    • Iterator Pattern Role composition

       iterator Role (Iterator): The iterator role is responsible for defining the interface for accessing and traversing elements ;

       specific iterator role (concrete Iterator): The specific iterator role to implement the iterator interface , and to record the current position in the traversal ;

       container Role (Container): The container role is responsible for defining the interface that creates the specific iterator role ;

       specific container roles (concrete Container): specific container roles implement interfaces that create specific iterator roles -the specific iterator role and the structure of the container related .

    • structure Diagram
                   

      As you can see from the structure, the iterator pattern adds an iterator role between the client and the container. With the addition of the iterator role, it is possible to avoid exposing the details inside the container, and to make the design conform to the principle of single responsibility.
        
        It is particularly important to note that in the iterator pattern, the specific iterator role and the specific container role are coupled --the traversal algorithm is closely related to the internal details of the container. In order to get the client program out of the dilemma of coupling with the specific iterator role, to avoid the change of the specific iterator role to the client program, the iterator pattern abstracts the specific iterator role, making the client program more general and reusable, which is called the polymorphic iteration .

    • Applicability

      1. accesses the contents of a container object without exposing its internal representation;

      2. supports multiple traversal of the container object;

      3. provides a unified interface for traversing different container structures (that is, support for polymorphic iterations).

2. Example

As the iterator pattern itself is loosely defined, there are a variety of implementations, and we'll just cite one example here. Before giving an example, let's start by enumerating how the iterator pattern is implemented.

    • The iterator role defines the traversed interface, but does not specify who will control the iteration. in the Java Collection framework, the process by which a client program controls traversal, called an external iterator , is also implemented by the iterator itself to control the iteration, known as an internal iterator . External iterators are more flexible and powerful than internal iterators, and internal iterators are weak in the Java language environment;

    • There is no rule in the iterator pattern to implement the traversal algorithm, as if it were to be implemented in the iterator role as a matter of course. because it facilitates the use of different traversal algorithms on a single container, it facilitates the application of a traversal algorithm to different containers. But this destroys the encapsulation of the container-the container role exposes its own private properties, which in Java means exposing its own private properties to other classes;

      Well, let's put it in the container role, so that the iterator role is raised to simply hold a function that traverses the current location. But the traversal algorithm is tightly tied to a specific container. In the Java Collection framework, the specific iterator role provided is the inner class defined in the container role, which protects the container's encapsulation. But the container also provides a traversal algorithm interface, and you can extend your own iterators.

      Let's look at the implementation of iterators in Java Collection:

//Iterator role that simply defines the traversal interface Public  interface Iterator<E> {    BooleanHasnext (); E next ();voidRemove ();//Container role, here is an example of a List, which indirectly implements the Iterable interface Public  interface Collection<e> extends iterable<e > {...    Iterator<e> Iterator (); ...} Public  interface List<e> extends Collection<e> { }//The specific container role is the ArrayList class that implements the List interface. To highlight the focus here, it refers to listing and iterator-related content Public Abstract  class abstractlist<E> extends abstractcollection <e> implements List<E> {......//This is the factory method responsible for creating the specific iterator role PublicIterator<e>iterator() {return NewItr ();}//Specific iterator role, which is in the form of an internal class. Abstractlist is for the purpose of extracting the public parts of each specific container role. //As the specific iterator role for the inner classPrivate  class Itr implements Iterator<E> {   intcursor =0;intLastret =-1;a "fast-fail" mechanism in a collection iteration that provides security for the collection during iteration. ArrayList in the presence of Modcount objects, additions and deletions will make the modcount++, through the comparison between the two, the iterator can quickly know whether there is list.add () similar operation in the iterative process, the existence of rapid failure!   intExpectedmodcount = Modcount; Public Boolean Hasnext() {returnCursor! = size (); } PublicObjectNext() {checkforcomodification ();//fast failure mechanism    Try{Object next = get (cursor); Lastret = cursor++;returnNext }Catch(Indexoutofboundsexception e) {checkforcomodification ();//fast failure mechanism     Throw NewNosuchelementexception (); } } Public void Remove() {if(Lastret = =-1)Throw NewIllegalStateException (); Checkforcomodification ();//fast failure mechanism    Try{abstractlist. This. Remove (Lastret);if(Lastret < cursor) cursor--; Lastret =-1; Expectedmodcount = Modcount;//fast failure mechanism}Catch(Indexoutofboundsexception e) {Throw NewConcurrentmodificationexception (); } }//fast failure mechanism   Final voidCheckforcomodification () {if(Modcount! = expectedmodcount)Throw NewConcurrentmodificationexception ();//Throws an exception, iteration terminates}}
    • use of the iterator pattern

      The client program has to get the specific container role, and then get the specific iterator role through the specific container role. This allows you to traverse the container with a specific iterator role ...

3. Applicable situation

We can see that the iterator pattern brings the following benefits to the application of the container:

1) supports traversing a container role in different ways. Depending on how they are implemented, there will be differences in effect (for example, iterator and Listiterator in list).

2) simplifies the interface of the container. In Java Collection, however, the container provides a traversal interface for extensibility.

3) simplifies the traversal approach. For the traversal of the object collection, it is still troublesome, for arrays or lists, we can still get through the cursor, but the user needs to understand the set is very clear premise, self-traversal objects, but for the hash table, the user traversal is more troublesome. With the introduction of the iterator method, the user is much simpler to use.

4) can provide a variety of traversal methods. For example, for a sequence of tables, we can provide a positive sequence traversal, in reverse order to traverse the two iterators, the user only need to get our implementation of a good iterator, we can easily traverse the collection.

5) Multiple traversal can be performed on the same container object. Because the traversal state is stored in each iterator object.

6) Good encapsulation, the user only need to get iterators can traverse, and for the traversal algorithm is not to care.

7) in Java Collection, iterators provide a quick fail mechanism (ArrayList is thread insecure, after the ArrayList class creates an iterator, unless the list structure is modified by the iterator itself remove or add. Otherwise, the list is modified in any form in any other thread, and the iterator throws an exception immediately and fails quickly, preventing the unsafe operation of iterations under multithreading.

 It is also possible to derive the applicable scope of the iterator pattern:

1) access the contents of a container object without exposing its internal representation;

2) supports multiple traversal of the container object;

3) provides a unified interface for traversing different container structures (polymorphic iterations).

Three, Iterator iterators and Iterable interfaces

1,Iterator iterator interface: Java.util package

  Java provides a specialized iterator interface Iterator, which we can implement for a container to provide a standard Java iterator.

    • Traversing a collection with Iterator mode

        The Iterator pattern is the standard access method used to traverse the collection class. It abstracts the access logic from different types of collection classes, thus avoiding exposing the internal structure of the collection to the client.

      For example, if you are not using Iterator, the way to traverse an array is to use an index:

for(int i=0

While traversing a hashset, you must use a while loop or foreach, but you cannot use a For loop:

while((e=e.next())!=null

For both of these methods, the client must know in advance the type of the collection (internal structure), the access code and the collection itself are tightly coupled, unable to detach the access logic from the collection class and the client code, resulting in each collection corresponding to a traversal method, the client code cannot be reused. even more frightening, if you later need to change ArrayList to LinkedList, the original client code must all be rewritten.

  To solve these problems, the iterator pattern always uses the same logic to iterate through the collection:

for

The secret is that the client itself does not maintain a "pointer" that iterates through the collection, and that all internal states (such as the current element's position and whether there is a next element) are maintained by Iterator, and this Iterator is generated by a factory method of the collection class, so it knows how to traverse the entire collection. Moreover, the client never deals directly with the collection class, it always controls the iterator, sends it "forward", "backwards", "takes the current element" instruction, it can indirectly traverse the entire collection.

First look at the definition of the Java.util.Iterator interface:

publicinterface Iterator {    boolean hasNext();     Object next();     void// 可选操作 

Depending on the first two methods you can complete the traversal, the typical code is as follows:

for// 对o的操作... } 

  polymorphic iterations: Each collection class may return a different Iterator specific type, and the Array may return Arrayiterator,set may return Setiterator,tree may return treeiterator, but they all implement The Iterator interface, so the client doesn't care what kind of Iterator it is, it just needs to get the Iterator interface, which is the power of object-oriented.

2. Iterable Interface: Java.lang bag

Java also provides a iterable interface, the function of the Iterable interface is "return" an iterator . The sub-interfaces we used to implement the interface are: Collection<e> series, including List<e>, Queue<e>, set<e>. It is particularly noteworthy that the Map interface does not implement the Iterable interface. the iterator () method of the interface returns a standard iterator implementation.

    • Implementing the Iterable interface to implement custom classes for foreach traversal

        The Iterable interface contains a Iterator () method capable of producing Iterator, and the Iterable interface is used by foreach to implement movement in the sequence. Therefore, implementing this interface allows the object to be the target of a foreach statement, and it is possible to traverse your underlying sequence through the foreach syntax.

      Before JDK1.5, the syntax for traversing a sequence with Iterator:

for// 对o的操作... } 

In JDK1.5 and later versions, foreach was introduced, simplifying the syntax of the above code (but limited to read-only, if remove, or using Iterator directly):

for

3. Speculation

    • Why do you have to implement iterable this interface? Why not implement the iterator interface directly?

        look at the collection classes in the JDK, such as the list family or set family, are implemented Iterable interface, but do not directly implement the Iterator interface. it makes sense to think about this: 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 (pointers) of the current iteration position. When a collection is passed between different methods, the result of the next () method becomes unpredictable because the current iteration position is not pre-provisioned. 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 (you cannot iterate the same sequence multiple times at the same time: You must wait until the current iteration is complete and reset before you can iterate again from scratch). Instead, the sequence implements the Iterable interface, and each call returns an iterator (Iterator) that counts from the beginning, so that there is no interference between multiple iterators.

Iv. foreach,iterator,for
    • The relationship between foreach and Iterator

        foreach is a new, jdk5.0, loop structure that can be used to work with each element in the collection regardless of the index of the collection.

The format is as follows:

for(variable:collection){ statement; }

Defines a variable that is used to stage each element in the collection and executes the corresponding statement (block). Collection must be an array or a class object that implements the Lterable interface.

As you can see, the advantage of using a Foreach Loop statement is that it is more concise, less error-prone, and does not care about the starting and ending values of the subscript. ForEach is not a keyword, a keyword or a for, statements are implemented by iterator, and their greatest difference lies in the Remove () method.

   In particular, the general invocation of the Delete and add methods is a concrete collection of methods, such as:

new ArrayList(); list.add(...); list.remove(...);...

However, if the remove () method of the collection is called during the loop, it causes a looping error because the size of the list.size () changes during the loop, resulting in an error ( Iterator的快速失败机制 ). So, if you want to delete an element of a collection in a looping statement, use the Remove () method of the iterator iterator, because its remove () method not only removes the element, but also maintains a flag that records whether it is currently a deleted state, for example, You cannot call its remove () method two times in a row, calling a call to the next () method at least once. Therefore, foreach is intended to make it easier to write in a form that iterates through the iterator. Of course, the function is not too full, so if you need to use the delete operation, then it should be used in its original form.

    • Using the For loop versus using the iterator iterator

      From the efficiency point of view:

      The use of ArrayList is faster than random access , and the Get () method in the For loop is a random access method, so the for loop is faster in ArrayList;

      The use of LinkedList is a faster sequential access , iterator in the next () method, the use of sequential access method, so in LinkedList, using iterator faster.

      From the data structure angle analysis:

        Using a For loop is a good place to access an ordered structure, you can quickly get the specified element based on the subscript, and the Iterator is suitable for accessing unordered structures, because iterators are positioned through next () and Pre () and can access a collection without order.

         The advantage of using Iterator is that you can iterate through the elements in the collection in the same way, regardless of the internal implementation of the collection class (as long as it implements the Java.lang.Iterable interface), and if you use Iterator to iterate through the elements in the collection, once you no longer use List instead Set to organize the data, the code that traverses the elements does not have to make any changes, and if you use the for to traverse, all the algorithms that traverse this set have to be adjusted accordingly, because the list is ordered, the set is unordered, the structure is different, and their access algorithms are not the same.

V. Brief introduction of Listiterator

1. Brief introduction

The Listiterator Series table iterator implements the Iterator<e> interface. The iterator allows the programmer to traverse the list in either direction, modify the list during iteration, and get the current position of the iterator in the list. The listiterator has no current element, and its cursor position is always located between the element returned by the call to previous () and the element returned by the call next (). an iterator with a list of length n has n+1 a possible pointer position, as illustrated by the following caret:

          

Note that the remove () and set (Object) methods are not defined according to the cursor position; they are defined based on the operation of the last element returned by calling next () or previous ().

2. Difference from Iterator

The main differences between Iterator and Listiterator are:

    • Listiterator has the Add () method, you can add objects to the list, and Iterator cannot;

    • Both Listiterator and Iterator have the Hasnext () and Next () methods, which enable sequential traversal. But Listiterator has hasprevious () and Previous () methods, which can be reversed (sequential forward) traversal, and Iterator can not;

    • Listiterator can use Nextindex () and Previousindex () to locate the current index position, while Iterator does not have this function;

    • Listiterator can be obtained through the Listiterator () method and the Listiterator (int index) method, and Iterator can only be obtained by the Iterator () method;

    • Both can implement delete objects, but listiterator can use the set () method to implement object modifications. Iterator can only traverse and cannot be modified. Because of these functions of listiterator, we can implement the operation of LinkedList, ArrayList and other list data structures.

Reference:

JDK APK 1.6.0
An iterative pattern for Java design patterns in layman's
23 Design Modes (13): Iterator mode
Java programmer from Dumb Bird to Rookie (45) Big Talk design mode (ix) iterator mode and command mode
Java iterators in-depth understanding and use
Java iterators
Iterator and Iterable
Java iterable interface and iterator iterators
Iterator and Listiterator

Overview of Java iterators

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.