Custom Iterators

An iterator traverses through every item in a collection. For example, in a while loop in Apex, you define a condition for exiting the loop, and you must provide some means of traversing the collection, that is, an iterator. In the following example, count is incremented by 1 every time the loop is executed (count++) :
while (count < 11) {
   System.debug(count);
      count++;
   }

Using the Iterator interface you can create a custom set of instructions for traversing a List through a loop. This is useful for data that exists in sources outside of Salesforce that you would normally define the scope of using a SELECT statement. Iterators can also be used if you have multiple SELECT statements.

Using Custom Iterators

To use custom iterators, you must create an Apex class that implements the Iterator interface.

The Iterator interface has the following instance methods:
NameArgumentsReturnsDescription
hasNextBooleanReturns true if there is another item in the collection being traversed, false otherwise.
nextAny typeReturns the next item in the collection.

All methods in the Iterator interface must be declared as global or public.

You can only use a custom iterator in a while loop. For example:
IterableString x = new IterableString('This is a really cool test.');

   while(x.hasNext()){
      system.debug(x.next());
   } 
Iterators are not currently supported in for loops.

Using Custom Iterators with Iterable

If you do not want to use a custom iterator with a list, but instead want to create your own data structure, you can use the Iterable interface to generate the data structure.

The Iterable interface has the following method:
NameArgumentsReturnsDescription
iteratorIterator classReturns a reference to the iterator for this interface.

The iterator method must be declared as global or public. It creates a reference to the iterator that you can then use to traverse the data structure.

In the following example a custom iterator iterates through a collection:
global class CustomIterable 
   implements Iterator<Account>{ 

   List<Account> accs {get; set;} 
   Integer i {get; set;} 

   public CustomIterable(){ 
       accs = 
       [SELECT Id, Name, 
       NumberOfEmployees 
       FROM Account 
       WHERE Name = 'false']; 
       i = 0; 
   }   

   global boolean hasNext(){ 
       if(i >= accs.size()) {
           return false; 
       } else {
           return true; 
       }
   }    

   global Account next(){ 
       // 8 is an arbitrary 
       // constant in this example
       // that represents the
       // maximum size of the list.
       if(i == 8){return null;} i++; return accs[i-1]; } }
The following calls the above code:
global class foo implements iterable<Account>{
   global Iterator<Account> Iterator(){
      return new CustomIterable();
   }
}
The following is a batch job that uses an iterator:
global class batchClass implements Database.batchable<Account>{ 
   global Iterable<Account> start(Database.batchableContext info){ 
       return new foo(); 
   }     
   global void execute(Database.batchableContext info, List<Account> scope){ 
       List<Account> accsToUpdate = new List<Account>(); 
       for(Account a : scope){ 
           a.Name = 'true'; 
           a.NumberOfEmployees = 69; 
           accsToUpdate.add(a); 
       } 
       update accsToUpdate; 
   }     
   global void finish(Database.batchableContext info){     
   } 
}
© Copyright 2000–2014 salesforce.com, inc. All rights reserved.
Various trademarks held by their respective owners.