カスタムイテレータ
イテレータは、コレクション内のすべての項目を辿ります。たとえば、Apex の while ループで、ループを終了する条件を定義し、コレクションを辿るいくつかの方法、つまりイテレータを提供する必要があります。次の例では、ループが実行されるごとに count が 1 ずつ増加します。
1while (count < 11) {
2 System.debug(count);
3 count++;
4 }Iterator インターフェースを使用して、ループ全体のリストを辿るためのカスタムの一連の指示を作成できます。イテレータは、通常 SELECT ステートメントを使用して範囲を定義する Salesforce 外の提供元にあるデータに役立ちます。複数の SELECT ステートメントがある場合にもイテレータを使用できます。
カスタムイテレータの使用
カスタムイテレータを使用するには、Iterator インターフェースを実装する Apex クラスを作成する必要があります。
Iterator クラスには次のインスタンスメソッドがあります。
| 名前 | 引数 | 戻り値 | 説明 |
|---|---|---|---|
| hasNext | Boolean | コレクション内の別の項目が辿られている場合は true が返され、そうでない場合は false が返されます。 | |
| next | anyType | コレクション内の次の項目を返します。 |
Iterator インターフェース内のすべてのメソッドは global または public として宣言する必要があります。
カスタムイテレータは while ループでのみ使用できます。次に例を示します。
イテレータは現在、for ループではサポートされていません。
1IterableString x = new IterableString('Th is a really cool test.');
2
3 while(x.hasNext()){
4 system.debug(x.next());
5 }Iterable とカスタムイテレータの使用
リストでカスタムイテレータを使用せずに独自のデータ構造を作成する場合、Iterable インターフェースを使用してデータ構造を生成できます。
Iterable インターフェースには次のメソッドがあります。
| 名前 | 引数 | 戻り値 | 説明 |
|---|---|---|---|
| iterator | Iterator クラス | このインターフェースのイテレータへの参照を返します。 |
iterator メソッドは global または public として宣言する必要があります。データ構造の走査に使用できるイテレータへの参照を作成します。
次の例では、コレクションのカスタムイテレータの例を示します。
1public class CustomIterator
2 implements Iterator<Account>{
3
4 private List<Account> accs;
5 private Integer currentIndex;
6
7 public CustomIterator(List<Account> accs){
8 this.accs = accs;
9 this.currentIndex = 0;
10 }
11
12 public boolean hasNext(){
13 return currentIndex < accs.size() - 1;
14 }
15
16 public Account next(){
17 if(hasNext()) {
18 currentIndex++;
19 return accs[currentIndex];
20 } else {
21 throw new NoSuchElementException();
22 }
23 }
24}1public class CustomIterable implements Iterable<Account> {
2 public Iterator<Account> iterator(){
3 List<Account> accs =
4 [SELECT Id, Name,
5 NumberOfEmployees
6 FROM Account
7 LIMIT 10];
8 return new CustomIterator(accs);
9 }
10}次は、イテレータを使用する一括処理ジョブです。
1global class BatchClass implements Database.Batchable<Account>{
2 global Iterable<Account> start(Database.BatchableContext info){
3 return new CustomIterable();
4 }
5 global void execute(Database.BatchableContext info, List<Account> scope){
6 List<Account> accsToUpdate = new List<Account>();
7 for(Account acc : scope){
8 acc.Name = 'true';
9 acc.NumberOfEmployees = 69;
10 accsToUpdate.add(acc);
11 }
12 update accsToUpdate;
13 }
14 global void finish(Database.BatchableContext info){
15 }
16}