---
schema_version: "1"
id: 9b644daa67b1176bc854a8264ded13837ac87a775261d6632a4958472ffae507
title: Custom Iterators
collection: legacydeveloper
version: current
locale: en-us
portal_url: https://docs.salesforce.com/legacydeveloper/current/en-us/apexcode/apex_classes_iterable.md
canonical_url: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_iterable.htm
source_site: developer.salesforce.com
content_type: documentation
content_hash: 6640a91174502a0b7b2c95b28b56fa3982db7eb33ce028e790f5eca406645e89
---
# Custom Iterators

An iterator traverses through every item in a collection. For example, in a procedural loop, you define a condition for exiting the loop, and you must provide some means of traversing the collection, that is, an iterator. In this example, count is incremented by 1 every time the loop is executed.

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. The iterator 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:

| Name | Arguments | Returns | Description |
| --- | --- | --- | --- |
| hasNext |  | Boolean | Returns true if there’s another item in the collection being traversed, false otherwise. |
| next |  | Any type | Returns the next item in the collection. |

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

This example code uses a custom iterator to iterate through a list of strings.

IterableString x = new IterableString('This is a really cool test.');

while(x.hasNext()){
   system.debug(x.next());
} 

## Using Custom Iterators with Iterable

If you don’t 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:

| Name | Arguments | Returns | Description |
| --- | --- | --- | --- |
| iterator |  | Iterator class | Returns 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:

public with sharing class CustomIterator
   implements Iterator<Account>{ 
 
   private List<Account> accounts;
   private Integer currentIndex;
 
   public CustomIterator(List<Account> accounts){
       this.accounts = accounts;
       this.currentIndex = 0;
   }
 
   public Boolean hasNext(){ 
       return currentIndex < accounts.size();
   }    
 
   public Account next(){
       if(hasNext()) {
           return accounts\[currentIndex++\];
       } else {
           throw new NoSuchElementException('Iterator has no more elements.');
       }
   } 
}

public with sharing class CustomIterable implements Iterable<Account> {
   public Iterator<Account> iterator(){
      List<Account> accounts =
      \[SELECT Id, Name,
       NumberOfEmployees 
       FROM Account
       WITH USER\_MODE
       LIMIT 10\];
      return new CustomIterator(accounts);
   }
}

The following is a batch job that uses an iterator:

public with sharing class BatchClass implements Database.Batchable<Account>{
   public Iterable<Account> start(Database.BatchableContext info){
       return new CustomIterable();
   }
   public void execute(Database.BatchableContext info, List<Account> scope){
       List<Account> accsToUpdate = new List<Account>();
       for(Account acc : scope){
           acc.Name = 'changed';
           acc.NumberOfEmployees = 69;
           accsToUpdate.add(acc);
       }
       update as user accsToUpdate;
   }
   public void finish(Database.BatchableContext info){
   }
}