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());
    }

When I enter this Java code in IntelliJ IDEA, the code analysis feature suggests that I replace the while loop with a for each loop since I'm iterating on a collection. Why is this?

InvalidBrainException
  • 2,312
  • 8
  • 32
  • 41
  • When you have to use an Iterator, such as when you use its remove() method, you can't win either way. In this case, in the for loop, it says 'for loop lacks update'. I like code inspection, but I generally find IntelliJ's unhelpfully noisy. – Michael Scheper Jul 17 '14 at 05:13

5 Answers5

25

This is what it wants you to use:

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

This has been in the language since Java 1.5, and is the idiomatic pattern. You need the Iterator only if you need access to the iterator's other methods (i.e. remove()).

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • 1
    This is simple and looks good but give concurrentModificationException. – Uday Sawant Dec 13 '14 at 09:58
  • 4
    This code does not modify anything. It cannot throw that exception. – Jim Garrison Dec 13 '14 at 17:22
  • Problem with using for (Object o : list) is that if the array is modified/accessed later on (happens a lot in games) it will throw an exception. If you use a Iterator with hasNext() it will not. So the suggestion is wrong. – Oliver Dixon Jul 12 '15 at 11:20
14

Because you are less likely to make mistakes and it looks better ; )

for( Object obj : list ) {
  System.out.println( obj.toString() );
}
James DW
  • 1,815
  • 16
  • 21
Tobias
  • 9,170
  • 3
  • 24
  • 30
  • Pardon my ignorance, but how is a 'while' loop more error prone than a 'for each' loop? – InvalidBrainException Oct 11 '11 at 15:58
  • 6
    With the while loop you have to handle the iterator by yourself and can forget to get the next element. With the for syntax you can't "forget" it. You have a loop which will output every element of the list exactly one time. You don't need to care about anything. – Tobias Oct 11 '11 at 15:59
11

because you have the inspection Java Language Migration Aids - 'while' loop replaceable with 'for each' active (which is the default), description is

This inspection reports for loops which iterate over collections or arrays, and can be replaced with the "for each" iteration syntax, available in Java 5 and newer. The setting Report java.util.List indexed loops is responsible for finding loops involving list.get(index) calls. These loops generally can be replaced with the foreach loops, unless they modify underlying list in the process, e.g. by calling list.remove(index). If latter is the case, foreach form of loop may throw ConcurrentModificationException. This inspection only reports if the project or module is configured to use a language level of 5.0 or higher.

so if you don't want to be told this then uncheck that box in the Inspections config

Matt
  • 8,367
  • 4
  • 31
  • 61
  • Thanks, I'm new to IntelliJ and to Java in general. I've had IntelliJ give me several useful suggestions about how to improve my code, but the description you quoted doesn't seem to explain _why_ replacing 'while' loops with 'for each' loops for collections/arrays is a better idea. – InvalidBrainException Oct 11 '11 at 15:57
  • to answer that I'd suggest looking at what the other people have said, though another reason if you have a specific requirement for indexed access. An example would be to avoid the object allocation incurred when accessing an arraylist via foreach. I don't think you'll have a requirement like this if you're new to java though so just use foreach. Another reason for using foreach is that it leaves the optimisation decision to the JVM which, given that the jvm is a dynamic optimiser, is also idiomatic to a jvm language. – Matt Oct 11 '11 at 19:31
2

The foreach loop is shorter to write and thus easier to read.

michael667
  • 3,241
  • 24
  • 32
1

The Foreach Loop however creates an anonymous class and consumes more memory compared to while loop, i would suggest to ignore the suggestion and use the while loop for better and optimized use of your code.

  • Can you provide a source for this? Using for-each loops has been the idiomatic way to handle these sort of loops for a long time now and are much more simple and concise than using a while loop, and this is the first I've heard about for-each loops being unoptimized. Any sort of difference here would be down to micro-optimization which [regular user's wouldn't need to worry or care about](https://softwareengineering.stackexchange.com/a/99463). – Hoppeduppeanut Apr 12 '21 at 06:43
  • Yes, regular user's wouldnt need to worry about micro-optimization but its a good practice to follow these norms and try to create the ideal code for organization. Pretty sure, organizations such as facebook, google which deals in huge amounts of data would like their employees to know such things and hence a good practice. detailed study on comparison can be found on the below link : https://www.lihaoyi.com/post/MicrooptimizingyourScalacode.html#:~:text=Things%20like%20removing%20intermediate%20objects,are%20examples%20of%20micro%2Doptimizations. – Shashank Goud Apr 15 '21 at 12:28