9

As I’m coding and discovering new ways of doing things in Java, I’m always somewhat perplexed in the better method of looping through lists to output data.

In the following example, I’m looping through lists and using a counter, so many times I’ve had to include an index counter in the output.

I'm partial to Method 1 but I found any of these method a bit dated. I’ve seen many examples of looping through lists and Method 2 is mostly used.

So my question is what is the better method, if all of these methods are just as equal, then what is the most standard?

private ArrayList<String> list = new ArrayList<String>();

public Test() {
    list.add("One");        
    list.add("Two");        
    list.add("Three");      
    list.add("Four");       
    list.add("Five");

    method1();
    method2();
    method3();
}

public void method1() {
    System.out.println("Method 1");
    int i = 1;
    for (String value:list) {
        System.out.println((i++) + " = " + value);
    }
}

public void method2() {
    System.out.println("Method 2");
    for (int i = 0; i < list.size(); i++) {
        System.out.println((i+1) + " = " + list.get(i));
    }
}

public void method3() {
    System.out.println("Method 3");
    Iterator<String> it = list.iterator();
    int i = 1;
    while (it.hasNext()) {
        System.out.println((i++) + " = " + it.next());
    }
}
GeekyDaddy
  • 384
  • 2
  • 12
  • possible duplicate of [Ways to iterate over a List in java?](http://stackoverflow.com/questions/18410035/ways-to-iterate-over-a-list-in-java) – Kenster Mar 24 '15 at 18:01
  • Kenster, thanks for letting me know of the possible duplicate. My question was more geared towards outputting with indexing. But I/we also found out that with the new version of Java 8 there are now new ways of looping through lists. – GeekyDaddy Mar 26 '15 at 13:11
  • You want to know which is better, but provide no criteria by which to assess which is better. – Raedwald Mar 31 '15 at 06:38

4 Answers4

18

method1() is similar to method3() as the for-each loop uses the List's iterator behind the scenes. The difference with method3() is that you actually have access to this iterator, so you can call remove on it if you wish to remove elements from the list.

method2()on the other hand can lead to "bad" performances depending on the underlying implementation. If your list is a LinkedList, get has O(n) complexity time so the for-loop will have O(n^2) complexity. With the iterator, you'll always get the next element in constant time.

I would personally use 1, it's also less code to write and this is one of the main benefit of the for-each loop if your intent is to perform a read-only operation on your data structure.

If you are using Java 8 and you don't need to print the index, you could also do:

list.forEach(System.out::println);
Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • 2
    `int index = 1; list.forEach(e->System.out.println((index++)+" = "+e));` You can print the index as well – Loki Mar 24 '15 at 12:39
  • 5
    @Loki No, a variable in a lambda must be effectively final. You could use an `AtomicInteger` although it's a bit overkill. – Alexis C. Mar 24 '15 at 12:40
  • 8
    You're right. I leave the comment though, so everyone can learn as I just did – Loki Mar 24 '15 at 12:42
  • As per your comment about removing elements with iterator, isn't changing the list while iterating over it a bad thing? Bad as in it can explode in your face with an exception. – Davor Mar 24 '15 at 18:27
  • 1
    @Davor Not via the iterator's remove method. The doc [states](http://docs.oracle.com/javase/tutorial/collections/interfaces/collection.html) _"Note that Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress."_ – Alexis C. Mar 24 '15 at 19:55
  • Wow. Java 8 is bomb because `list.forEach(System.out::println);` is awesome. – Jeel Shah Mar 24 '15 at 20:05
2

The first is better and least error prone.

public void method1() {
    System.out.println("Method 1");
    int i = 1;
    for (String value:list) {
        System.out.println((i++) + " = " + value);
    }
}

The second options is tightly coupled with the Collection you are using. It means, if someone changes the data structures then he/she has to change the code for the for loop as well.

The third option, Iterators can get ugly when you have to use nested loops and have to deal with multiple iterators.

Have a look at following link to see the error prone usage of iterators. https://docs.oracle.com/javase/8/docs/technotes/guides/language/foreach.html

suranjan
  • 447
  • 2
  • 4
-1

method3() where Iterator is used is the best way to iterate through a list. Even though method1() uses Iterator behind the scenes, if you want to modify the list inside the loop, like update or delete, it might lead to ConcurrentModificationException.

Magnilex
  • 11,584
  • 9
  • 62
  • 84
Ganesh chaitanya
  • 638
  • 6
  • 18
-3

None of them. Use lambda expressions, available in java 8.

Or Guava functions if using Java < 8.

NimChimpsky
  • 46,453
  • 60
  • 198
  • 311