IntelliJ建议用for each循环替换while循环。为什么?

25
    ArrayList<Object> list = new ArrayList<Object>();
    list.add(12);
    list.add("Hello");
    list.add(true);
    list.add('c');

    Iterator iterator = list.iterator();
    while(iterator.hasNext())
    {
        System.out.println(iterator.next().toString());
    }

当我在IntelliJ IDEA中输入此Java代码时,代码分析功能建议我将while循环替换为for each循环,因为我正在对集合进行迭代。为什么会这样?


当你不得不使用迭代器时,例如当你使用它的remove()方法时,无论如何都无法赢。在这种情况下,在for循环中,它会显示“for循环缺少更新”。我喜欢代码检查,但通常发现IntelliJ的噪音太多而不够有用。 - Michael Scheper
5个回答

25

它想让你使用的是:

for (Object o : list)
{
    System.out.println(o.toString());
}

自Java 1.5起,这一语言特性就已经存在了,并且是惯用模式。只有在需要访问迭代器的其他方法(即remove())时才需要使用Iterator。


1
这很简单,看起来不错,但会产生concurrentModificationException。 - Uday Sawant
4
这段代码不会修改任何东西。它也不可能抛出那个异常。 - Jim Garrison
使用 for (Object o : list) 的问题在于,如果数组稍后被修改/访问(在游戏中经常发生),它将抛出异常。如果使用具有 hasNext() 的 Iterator,则不会出现此问题。因此,建议是错误的。 - Oliver Dixon

14

因为这样做,你犯错的可能性更小,而且看起来更好;)

for( Object obj : list ) {
  System.out.println( obj.toString() );
}

请原谅我的无知,但是相较于“for each”循环,为什么“while”循环更容易出错呢? - InvalidBrainException
6
使用 while 循环时,需要自己处理迭代器,并且可能会忘记获取下一个元素。使用 for 语法就不会“忘记”它。你将得到一个循环,可以精确地输出列表的每个元素一次。你不需要担心任何事情。 - Tobias

11
因为您启用了Java语言移植助手中的"for each"循环替换"while"循环检查(该选项默认开启),此检查报告循环遍历集合或数组的代码,可以使用Java 5及更高版本中提供的"for each"迭代语法进行替换。报告java.util.List索引循环的设置负责查找涉及列表.get(index)调用的循环。通常情况下,这些循环可以用foreach循环进行替换,除非它们在过程中修改了底层的列表,例如通过调用list.remove(index)。如果是后者,则循环的foreach形式可能会抛出ConcurrentModificationException异常。此检查仅在项目或模块配置为使用5.0或更高语言级别时报告。如果您不想收到此提示,请在检查配置中取消勾选相应选项。

谢谢,我对IntelliJ和Java都不太熟悉。IntelliJ给了我几个有用的建议来改进我的代码,但是你引用的描述似乎没有解释为什么用“for each”循环取代集合/数组中的“while”循环是一个更好的选择。 - InvalidBrainException
回答这个问题,我建议看看其他人说了什么,不过如果你有对索引访问的特定要求,那么另一个原因就是使用foreach来避免在访问arraylist时产生对象分配。不过,如果你是Java新手,我认为你不会有这样的要求,所以只需使用foreach即可。使用foreach的另一个原因是它将优化决策留给JVM,而考虑到JVM是一个动态优化器,这也是JVM语言的惯用方式。 - Matt

2

foreach循环语句写法更短,因此更易于阅读。


1

Foreach循环会创建一个匿名类,相比while循环会消耗更多的内存。我建议忽略这个建议,使用while循环以获得更好优化的代码。


你能提供这个的来源吗?使用for-each循环一直是处理这些循环的惯用方式,比使用while循环更简单、更简洁,这是我第一次听说for-each循环不被优化。任何差异都将归结于微观优化,而普通用户不需要担心或关心 - Hoppeduppeanut
是的,普通用户不需要担心微观优化,但遵循这些规范并尝试创建理想代码对于组织来说都是一个好习惯。我相信像Facebook、Google这样处理大量数据的组织会希望他们的员工了解这些内容,因此这是一个好习惯。有关比较的详细研究可以在以下链接中找到:https://www.lihaoyi.com/post/MicrooptimizingyourScalacode.html#:~:text=Things%20like%20removing%20intermediate%20objects,are%20examples%20of%20micro%2Doptimizations. - Shashank Goud

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接