Java中的Iterator和Foreach

作者: Arvin Chen 分类: Java 来源: Break易站(www.breakyizhan.com)

Java中的Iterator和Foreach的背景

Iterator是集合框架提供的接口,用于遍历集合以及集合中项目的顺序访问。

   // Iterating over collection 'c' using terator
   for (Iterator i = c.iterator(); i.hasNext(); ) 
       System.out.println(i.next());

 

Foreach循环,用于遍历集合中的项目。

   // Iterating over collection 'c' using for-each 
   for (Element e: c)
       System.out.println(e);

我们将for-each循环中使用的':'读作“in”。因此循环读取为“对于元素中的每个元素e”,这里元素是存储元素类型项的集合。

注意:在使用lambda表达式的Java 8中,我们可以简单地用for替换for-each循环

elements.forEach(e  - > System.out.println(e));

 

Java中的Iterator和Foreach两次遍历之间的差异

在for-each循环中,我们不能修改集合,另一方面它会抛出一个ConcurrentModificationException,迭代器我们可以修改集合。

修改集合只是意味着删除元素或更改集合中存储的项目的内容。发生这种情况是因为for-each循环隐式地创建了一个迭代器,但它没有向用户公开,因此我们无法修改集合中的项目。

什么时候使用哪个遍历?

  • 如果我们必须修改集合,我们可以使用Iterator。
  • 使用嵌套for循环时,最好使用for-each循环,考虑下面的代码以便更好地理解。
// Java program to demonstrate working of nested iterators
// may not work as expected and throw exception.
import java.util.*;

public class Main
{
    public static void main(String args[])
    {
        // Create a link list which stores integer elements
        List<Integer> l = new LinkedList<Integer>();

        // Now add elements to the Link List
        l.add(2);
        l.add(3);
        l.add(4);

        // Make another Link List which stores integer elements
        List<Integer> s=new LinkedList<Integer>();
        s.add(7);
        s.add(8);
        s.add(9);

        // Iterator to iterate over a Link List
        for (Iterator<Integer> itr1=l.iterator(); itr1.hasNext(); )
        {
            for (Iterator<Integer> itr2=s.iterator(); itr2.hasNext(); )
            {
                if (itr1.next() < itr2.next())
                {
                    System.out.println(itr1.next());
                }
            }
        }
    }
}

输出:

Exception in thread "main" java.util.NoSuchElementException
    at java.util.LinkedList$ListItr.next(LinkedList.java:888)
    at Main.main(Main.java:29)

上面的代码抛出了java.util.NoSuchElementException。

在上面的代码中,我们一次又一次地为itr1调用next()方法(即,对于List l)。现在我们正在推进迭代器,甚至没有检查它是否在集合中留下了更多元素(在内部循环中),因此我们推进迭代器的次数超过集合中导致NoSuchElementException的元素数量。

for-each循环是为嵌套循环量身定制的。用以下代码替换迭代器Iterator代码。

// Java program to demonstrate working of nested for-each
import java.util.*;
public class Main
{
    public static void main(String args[])
    {
        // Create a link list which stores integer elements
        List<Integer> l=new LinkedList<Integer>();

        // Now add elements to the Link List
        l.add(2);
        l.add(3);
        l.add(4);

        // Make another Link List which stores integer elements
        List<Integer> s=new LinkedList<Integer>();
        s.add(2);
        s.add(4);
        s.add(5);
        s.add(6);

        // Iterator to iterate over a Link List
        for (int a:l)
        {
            for (int b:s)
            {
                if (a<b)
                    System.out.print(a + " ");
            }
        }
    }
}

输出:

2 2 2 3 3 3 4 4

使用for-each循环或迭代器遍历集合可以提供相同的性能。在这里,表现我们指的是这两次遍历的时间复杂性。

如果使用旧样式的C for循环进行迭代,那么我们可能会大大增加时间复杂度。

//这里l是List,它可以是ArrayList / LinkedList,n是List的大小

for (i=0;i<n;i++)
   System.out.println(l.get(i));

这里,如果列表l是一个ArrayList,那么我们可以在O(1)时间内访问它,因为它被分配了连续的内存块(就像一个数组),即随机访问是可能的。但是如果集合是LinkedList,那么随机访问是不可能的,因为它没有分配连续的内存块,所以为了访问一个元素,我们必须遍历链接列表,直到你到达所需的索引,因此所用的时间访问元素的最坏情况是O(n)。

对于没有随机访问的集合,Iterator和for-each循环比简单的循环更快,而在允许随机访问的集合中,for-each循环/ for循环/迭代器没有性能变化。

  •   本文标题:Java中的Iterator和Foreach - Break易站
    转载请保留页面地址:https://www.breakyizhan.com/java/5281.html
    扫描二维码添加微信 
  • ,领取淘宝优惠券,淘宝购物更优惠。现在添加微信,还可以领取机械键盘优惠券!添加微信后,分享淘宝选中的机械键盘给淘宝机器人即可领取!
    支持我们,就用微信淘宝!

    发表笔记

    电子邮件地址不会被公开。 必填项已用*标注

    更多阅读