在Enhanced for循环和老式的基于索引的循环之间进行选择,程序执行是否会有所不同



我在一次采访中被问到这个问题。我说没有。面试官似乎并没有留下深刻印象。

我遗漏了哪个角落的案子?

注意:我不是在谈论可以更快地迭代两次/修改循环变量的情况。

换句话说,之间的任何差异

for (int i = 0;i<set.size();i++)
{
// do something
}

for (int x : set)
{
// do something.
}

任何有性能的东西(我知道它们都编译成相同的代码)等。

答案是:是的,程序的行为可能不同。

Kayaman在他的回答中已经提到了线程安全。这是一个特殊情况,可能会显示不同的行为。集合本身是否在迭代过程中被修改是可能影响程序流的一个方面。

但不管怎样,通过增强的for循环,迭代器是在循环的开头创建的。这个迭代器将保留对他正在迭代的"his"集合的引用。与此相反,当集合被新集合替换时,将考虑使用经典for循环的迭代。

这可以在以下示例中看到。

import java.util.ArrayList;
import java.util.List;
public class DifferentForLoops
{
    public static void main(String[] args)
    {
        DifferentForLoops d = new DifferentForLoops();
        d.startOld();
        d.startNew();
    }
    private List<Integer> list;
    private void createList(int size)
    {
        list = new ArrayList<Integer>();
        for (int i=0; i<size; i++)
        {
            list.add(i);
        }
    }
    public void startOld()
    {
        createList(10);
        for (int i = 0;i<list.size();i++)
        {
            System.out.println("Old: Entry "+list.get(i)+" of "+list);
            pause();
            list = list.subList(0, list.size()-1);
        }        
    }
    public void startNew()
    {
        createList(10);
        for (int a : list)
        {
            System.out.println("New: Entry "+a+" of "+list);
            pause();
            list = list.subList(0, list.size()-1);
        }        
    }
    private static void pause()
    {
        try
        {
            Thread.sleep(500);
        }
        catch (InterruptedException e)
        {
            Thread.currentThread().interrupt();
        }
    }
}

是的,假设你有类似的for循环

for(int i=0;i<5;i++){ 
// you manipulate i value and increase or decrease
i++;

 //  i--;

}

将对循环迭代产生影响,这是下一次它将取lates i的值。但是对于每个环路

for(int i: somearray){ 

  // you manipulate i's value.
i++;
// its not going to effect the iteration suppose somearray has length of 5 it iterate 5 times
}

在一个索引为Collection的标准(即JDK中定义的标准)中,不会有任何区别。但是,Iterator没有定义迭代顺序,因此可以有一个Iterator来向后遍历集合,而for循环则向前遍历(即从索引0到大小-1)。

当涉及多线程时,Iterators也可以具有不同的功能,因此线程安全的Iterator可能会给出集合的一致视图,而使用for循环迭代可能会给出未定义的结果。

不过,我相信面试官的期望不仅仅是"不",所以这可能是他不满意的主要原因。

增强的for循环是一个接一个地迭代您的列表,在旧的for循环中,您可以像一样跳跃来循环

for(int i=0;i<100;i+=4){ 
}

但若你们要一个接一个地阅读,两者都是一样的,甚至是增强了循环的可读性和小而甜。

最新更新