A detailed explanation of For-each loops and iterative _java in Java

Source: Internet
Author: User
Tags int size iterable static class throw exception concurrentmodificationexception

When learning Java collection, it is noted that the collection level root interface collection implements the Iterable<t> interface (located in the Java.lang package), which enables the object to be "foreach" The target of the statement, and the only method in this interface is to return an iterator that iterates over an element of a group of T types.

First, iterator iterator

Interface:iterator<t>

Public interface iterator<e>{
  boolean hasnext (); 
 E next (); 
 void Remove ();
 }

Look at the iterator interface API to know that this is an iterator that iterates over the collection. Iterators allow callers to use well-defined semantics to remove elements from the collection that the iterator points to during the iteration.

Of particular note is the use of this iterator remove () method: Remove the last element returned by the iterator (optional operation) from the collection pointed to by the iterator. This method can only be called once per call to next. The behavior of the iterator is indeterminate if the collection that the iterator points to is modified in a way other than by calling this method (the Remove method) when iterating. The interface designer has pointed out in the design of the Iterator<t> interface that if the Remove () method in addition to the iterator is invoked to modify the collection that the iterator points to, it can result in uncertainty. What happens depends on the specific implementation of the iterator. In the case of this uncertain consequence, one of the things encountered in learning ArrayList is that an iterator throws a Concurrentmodificationexception exception. The specific exception situation is shown in the following code:

Import java.util.ArrayList;
Import java.util.Collection;
Import Java.util.Iterator;

public class Itaratortest {public

  static void Main (string[] args) {
    collection<string> list = new ArrayList <String> ();
    List.add ("Android");
    List.add ("IOS");
    List.add ("Windows Mobile");

    Iterator<string> iterator = List.iterator ();
    while (Iterator.hasnext ()) {
      String lang = Iterator.next ();
      List.remove (lang);//will throw Concurrentmodificationexception
    }}}



This code throws a Concurrentmodificationexception exception at run time because we do not delete the element with the iterator remove () method during the iterator run, but instead use the ArrayList remove () Method changes the collection that the iterator points to. This violates the design principle of the iterator, so an exception occurred.

The reported exceptions are as follows:

Exception in thread "main" java.util.ConcurrentModificationException
At Java.util.arraylist$itr.checkforcomodification (arraylist.java:859)
At Java.util.arraylist$itr.next (arraylist.java:831)
At Text.ItaratorTest.main (itaratortest.java:17)

Second, For-each cycle and iterator iterator<t>

From Java5, there is a For-each loop in Java that can be used to iterate through collection and array. The Foreach loop allows you to invoke the Hasnext () in the while loop without having to keep the index in the traditional for loop, or when using iterator/listiterator (an iterator implementation in ArrayList) method to traverse the collection. The For-each loop simplifies the traversal of any collection or array. But there are two points to be aware of using the Foreach loop.

Objects that use a Foreach loop must implement the Iterable<t> interface

Take a look at the following example:

Import java.util.ArrayList; public class ForeachTest1 {public static void main (String args[]) {customcollection<string> mycollection =
    New Customcollection<string> ();
    Mycollection.add ("Java");
    Mycollection.add ("Scala");

    Mycollection.add ("Groovy"); What does this code would do, print language, throw exception or//compile time error for (String language:my
    Collection) {System.out.println (language);

    } private class Customcollection<t> {private arraylist<t> bucket;
    Public CustomCollection () {bucket = new ArrayList ();
    public int size () {return bucket.size ();
    public Boolean IsEmpty () {return bucket.isempty ();
    Public Boolean contains (T-o) {return bucket.contains (o);
    Public boolean Add (T e) {return bucket.add (e);
    public boolean Remove (T-o) {return bucket.remove (o);

 }

  }
}

The above code will not compile, because the CustomCollection class in the code does not implement the Iterable<t> interface, and the error of the compile period is as follows:

Exception in thread "main" java.lang.Error:Unresolved compilation problem:
Can only iterate a array or an instance of java.lang.Iterable

At Text.ForeachTest1.main (foreachtest1.java:15)

In fact, there is no need to wait until the compile time to find the error, and Eclipse will display the errors in the Foreach loop after this code has been written: Can only iterate over a array or an instance of java.lang.Iterable

As you can confirm again from the example above, the Foreach loop is only applicable to objects that implement the Iterable<t> interface. Because all built-in collection classes implement the Java.util.Collection interface and have inherited the iterable, in order to solve the above problems, you can choose to simply let CustomCollection implement the collection interface or inherit Abstractco Llection. The solution is as follows:

Import java.util.AbstractCollection;
Import java.util.ArrayList;

Import Java.util.Iterator; public class Foreachtest {public static void main (String args[]) {customcollection<string> mycollection = NE
    W customcollection<string> ();
    Mycollection.add ("Java");
    Mycollection.add ("Scala");
    Mycollection.add ("Groovy");
    for (String language:mycollection) {System.out.println (language); } private static Class Customcollection<t> extends Abstractcollection<t> {private ARRAYLIST&LT;T&G T

    Bucket
    Public CustomCollection () {bucket = new ArrayList ();
    public int size () {return bucket.size ();
    public Boolean IsEmpty () {return bucket.isempty ();
    Public Boolean contains (Object o) {return bucket.contains (o);
    Public boolean Add (T e) {return bucket.add (e);
    public boolean remove (Object o) {return bucket.remove (o);
    } @OverridePublic iterator<t> iterator () {//TODO auto-generated a stub return Bucket.iterator ();

 }
  }
}

The internal implementation of the 2.foreach loop is also based on iterator.

To verify that the Foreach loop is using iterator as an internal implementation, we still use the first instance of this article to validate:

public class Itaratortest {public

  static void Main (string[] args) {
    collection<string> list = new ArrayList <String> ();
    List.add ("Android");
    List.add ("IOS");
    List.add ("Windows Mobile");

    Example1
    //iterator<string> iterator = List.iterator ();
    while (Iterator.hasnext ()) {
    //String lang = Iterator.next ();
    List.remove (lang);
    }

    //Example 2 for
    (String language:list) {
      list.remove (language);
  }

}}

Exception reported when the program was run:

Exception in thread "main" java.util.ConcurrentModificationException
At Java.util.arraylist$itr.checkforcomodification (arraylist.java:859)
At Java.util.arraylist$itr.next (arraylist.java:831)
At Text.ItaratorTest.main (itaratortest.java:22)

This exception is a description of the For-each loop using iterator to traverse the collection, which also calls Iterator.next (), which checks for (element) changes and throws Concurrentmodificationexception.

Summarize:

    • When traversing collection, if you want to modify the collection during traversal, you must implement it through Iterator/listiterator, otherwise the "uncertain consequences" may occur.
    • The Foreach loop is implemented through iterator, and objects using the Foreach loop must implement the Iterable interface

The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.

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.