简体   繁体   中英

Enhanced for loop

I often come across cases where I want to use an enchanced for-loop for some Collection or array that I get from some object.

eg

items = basket.getItems();
for (int item : items) {
    // Do something
}

Another way to do that is:

for (int item : basket.getItems()) {
    // Do something
}

The second one is more compact and improves readability in my opinion, especially when the item variable won't be used anywhere else.

I would like to know whether the getter in the for statement has any impact in performance. Will it be optimized to something similar to the 1st one? Or will it access the getter every time? Of course the getItems() might do something quite slow (eg network access, etc)

Question is similar to some others, but is referring to the getter of the collection/array itself and not the size of it. However, it may be the same case in the end.

The getItems() method will be called only once in both cases. There is no difference between the two, apart from one using an extra local variable which you could use somewhere else.

As you can read in JLS 14.14.2 , the enhanced for loop is translated roughly to this traditional for loop:

 for (I #i = Expression.iterator(); #i.hasNext(); ) { TargetType Identifier = (TargetType) #i.next(); Statement } 

#i is an automatically generated identifier that is distinct from any other identifiers (automatically generated or otherwise) that are in scope (§6.3) at the point where the enhanced for statement occurs.

From here it's clear that Expression is evaluted only once.

As you can see on the following code sample, on the enhanced for, the initialization of the collection on which to iterate is done only once. So, the second choice is more compact, and does not impact performance.

package test;

public class Main {

        static class Basket {
            int[] items = { 1, 2, 3 };

        public int[] getItems() {
                System.out.println("in getItems()");
            return items;
        }

    }

    public static void main(String[] args) {
        Basket basket = new Basket();
        for (int item : basket.getItems()) {
            System.out.println(item);
        }

    }
}

Yes second one improves readability of code.

if you are getting the objects from network and then iterating over it in a for loop then I think yes it has performance impact because you are making network access every time and that is inefficient also as for a small/single object doing network access is not recommended. instead of that get it once from network access store it locally and iterate over it

thus 1st option is performance optimized in network access case if your object is local then any method will do. there wont be much performance difference.

I don't think it will call getter every time. If it does it will get new list every time and Loop wont break. You can test this by putting simple Sysout inside getter method. Performance will be same in these two cases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM