Which one is the best way to iterate the elements of a particular collection?

I always use for each loop while going through the elements of a particular collection.

Just to check how much time each looping process consumes, i coded like this,

public class LoopingDemo {
    static ArrayList<String> arrayList = new ArrayList<String>();
    static double start;
    static double end;

    public static void iterator() {
        simpleForLoop();
        System.out.println();
        forEachLoop();
        System.out.println();
        useWhileLoop(arrayList);
        System.out.println();
        useForLoop(arrayList);
        System.out.println();
        enumerator();
    }
    public static void simpleForLoop(){
        start = System.nanoTime();
        for(int i=0;i<arrayList.size();i++){
            String str = arrayList.get(i);
            System.out.println(": "+str);
        }
        end = System.nanoTime();
        System.out.println("Taken taken in simpleForLoop process: "
            + (end - start));
    }

    public static void forEachLoop() {
        start = System.nanoTime();
        for (String str : arrayList) {
        System.out.println(str);
    }
        end = System.nanoTime();
        System.out.println("Taken taken in forEachLoop process: "
            + (end - start));
    }

    public static void enumerator() {
        start = System.nanoTime();

        // get the Enumeration object
        Enumeration<String> en = Collections.enumeration(arrayList);

        // enumerate through the ArrayList elements
        System.out.println("Enumerating through Java ArrayList");

        while (en.hasMoreElements()) {
            System.out.println(en.nextElement());
            /*
             * String name = (String) en.nextElement();
             * System.out.println(name);
             */
        } 
        end = System.nanoTime();
        System.out.println("Taken taken in enumeration process: "
            + (end - start));
    }

    private static void useWhileLoop(Collection<String> myList) {
        start = System.nanoTime();
        Iterator<String> itr = myList.iterator();
        while (itr.hasNext()) {
            String str = itr.next(); // Returns the next element in the
                                    // iteration.
            System.out.println(str);
            // System.out.println(itr.next()); // in one line
        }
        end = System.nanoTime();
        System.out.println("Taken taken in useWhileLoop process: "
            + (end - start));
    }

    /**
     * Note that this for-loop does not use an integer index.
     */
    private static void useForLoop(Collection<String> myList) {
        start = System.nanoTime();
        for (Iterator<String> itr = myList.iterator(); itr.hasNext();) {
            System.out.println(itr.next());
        }
        end = System.nanoTime();
        System.out.println("Taken taken in useForLoopWithIterator process: "
            + (end - start));
    }

    public static void addElements() {

        // Add elements to the array list.
        arrayList.add("C");
        arrayList.add("A");
        arrayList.add("E");
        arrayList.add("B");
        arrayList.add("D");
        arrayList.add("F");
        arrayList.add(1, "A2");

    }

    public static void main(String[] args) {
        addElements();
        iterator();

    }

}

Surprisingly, the looping process done through for each loop only lags behind the simple for loop.(Results may vary on different machines with different configurations.)

Console output:

Taken taken in simpleForLoop process:              853200.0
Taken taken in forEachLoop process:                788993.0
Taken taken in useWhileLoop process:               452014.0
Taken taken in useForLoopWithIterator process:     299775.0
Taken taken in enumeration process:                766756.0

So why do the people prefer to do it through the for each loop? Is there any reason based on performance?

Upvotes: 4

Views: 105

Answers (4)

Adrian Shum
Adrian Shum

Reputation: 40036

IIRC, for-each loop is simply a syntax sugar that will be compiled to for loop with iterator when iterating thru a collection. On runtime there should be no performance difference.

The difference you see is a typical result of a poorly written benchmarking logic. If you put "for loop with iterator" as the first method to call, you will find it run slow.

Not to mention the duration for each test is too short to be significant, after I have added some warm up (run everything 5 times first, and look at the result of the 6th result), the result become normal:

Taken taken in useForLoopWithIterator process: 105110.0
Taken taken in simpleForLoop process: 122181.0
Taken taken in useWhileLoop process: 104774.0
Taken taken in enumeration process: 123520.0
Taken taken in forEachLoop process: 106782.0

The result of forEachloop, useForLoopWithIterator and useWhileLoop is almost identical (for which they should be). Index-based access when iterating thru collection is almost least-preferred. Although the difference is not significant here, you will see a bigger difference if you are using non-array-based collection, e.g. LinkedList.

Upvotes: 1

Jose Leon
Jose Leon

Reputation: 1651

The book Effective Java covers this. Basically, foreach is concise and elegant for anyone to read and understand the code. It's always said never to optimize prematurely. Only look at optimizing when you are absolutely certain it's needed. So if you find that it's very common to find foreach it's because it's been because it's easier to understand, maintain and optimizing has been determined not needed at that moment.

Upvotes: 0

Tobias
Tobias

Reputation: 5108

As long as code is fast enough, I would go for simplicity/maintainability. Only if performance becomes an issue would I consider optimizing. And even then, there might be parts of the workflow that will yield much greater performance gains when optimizing.

Upvotes: 0

HYJ
HYJ

Reputation: 3

I use it for convenience. You don't need to consider the boundary and condition with "for (Type e : set).

Upvotes: 0

Related Questions