58

I just have a simple question about how list for loops work that has been bugging me. Does the for loop variable refer to the actual list item? Here's what I mean:

Say I have a list of accounts.

List<Account> accountList = new List<Account>();
accountList = [SELECT Id FROM Account];

And I write a for loop like so:

for(Account a: accountList){
  a.Name = 'whatever';
}
update accountList;

Is that the same as:

for(Integer a = 0; a < accountList.size(); a++){
  accountList[a].Name = 'whatever';
}
update accountList;

In other words, is a in the first loop just a shorthand for accountList[a] ?

Thanks for answering this admittedly basic question. The Force.com Apex workbook wasn't very explicit, and I had a hard time Googling it.

2 Answers 2

58

No. They are not the same thing. There are differences in the way they work.

In your example, they accomplish the same thing - you do indeed get a reference in each case to the element you want, and you are able to manipulate it. Maybe that's what you were asking, but it's important to understand the differences between the constructs.

In the enhanced for loop, under the covers, you are given an iterator which is backed by your list. This iterator tracks where you are in the underlying list and gives you the current / next item. In Apex, as in Java, iterators are convenient but they have a drawback: you can't modify the underlying collection during iteration. (More on this in a sec.)

In a "normal" index-based for loop, all you are doing is incrementing a counter each time, and then (if you wish), using that counter as the index into a list.

In general, the enhanced for loop is easier for developers and saves you a few characters of code and looks prettier. However, there are two very common use cases where you can't use an enhanced for loop.

1) When you want to add/remove items from the collection during iteration. This trivial example will throw a "Cannot modify a collection while it is being iterated." exception in Apex:

List<String> testloop = new List<String>();
testloop.add('a');
testloop.add('b');
for (String astring : testloop) {
    testloop.remove(0);
}

But this will not:

List<String> testloop = new List<String>();
testloop.add('a');
testloop.add('b');
for (Integer i = 0; i < testloop.size(); i++) {
    testloop.remove(0);
}

(The second example, besides being horribly inefficient, also demonstrates why you need to be careful when modifying lists during iteration - it has a bug in it.)

2) When you need to get at matching elements in two separate lists at the same time. This is VERY common in Apex.

for (Integer i = 0; i < testloop.size(); i++) { // testloop and testloop2 are known to be identical in size
    if (testloop[i] != testloop2[i]) {
        // do something
    }
}

Hope that helps.

0
5

Yes this is a feature in JAVA and C# which is also available in APEX.

Search for "for-each" loop.

Basically the first type of for loop is very convenient in APEX development when you need to iterate over all objects in the list and perform some operation like in your example.

I rarely use the second type of for loop in APEX but it is essentially the same IMO.

Also see:

http://www.salesforce.com/us/developer/docs/apexcode/Content/langCon_apex_loops.htm

https://stackoverflow.com/questions/5851025/why-are-there-two-different-kinds-of-for-loops-in-java

0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .