カスタムイテレータ
イテレータは、コレクション内のすべての項目を辿ります。たとえば、Apex の while ループで、ループを終了する条件を定義し、コレクションを辿るいくつかの方法、つまりイテレータを提供する必要があります。次の例では、ループが実行されるごとに (count++)、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('This is a really cool test.');
2
3 while(x.hasNext()){
4 system.debug(x.next());
5 }Iterable とカスタムイテレータの使用
リストでカスタムイテレータを使用せずに独自のデータ構造を作成する場合、Iterable インターフェースを使用してデータ構造を生成できます。
Iterable インターフェースには次のメソッドがあります。
| 名前 | 引数 | 戻り値 | 説明 |
|---|---|---|---|
| iterator | Iterator クラス | このインターフェースのイテレータへの参照を返します。 |
iterator メソッドは global または public として宣言する必要があります。データ構造の走査に使用できるイテレータへの参照を作成します。
次の例では、コレクションのカスタムイテレータの例を示します。
1global class CustomIterable
2 implements Iterator<Account>{
3
4 List<Account> accs {get; set;}
5 Integer i {get; set;}
6
7 public CustomIterable(){
8 accs =
9 [SELECT Id, Name,
10 NumberOfEmployees
11 FROM Account
12 WHERE Name = 'false'];
13 i = 0;
14 }
15
16 global boolean hasNext(){
17 if(i >= accs.size()) {
18 return false;
19 } else {
20 return true;
21 }
22 }
23
24 global Account next(){
25 // 8 is an arbitrary
26 // constant in this example
27 // that represents the
28 // maximum size of the list.
29 if(i == 8){return null;}
30 i++;
31 return accs[i-1];
32 }
33}次で、上記のコードをコールします。
1global class foo implements iterable<Account>{
2 global Iterator<Account> Iterator(){
3 return new CustomIterable();
4 }
5}次は、イテレータを使用する一括処理ジョブです。
1global class batchClass implements Database.batchable<Account>{
2 global Iterable<Account> start(Database.batchableContext info){
3 return new foo();
4 }
5 global void execute(Database.batchableContext info, List<Account> scope){
6 List<Account> accsToUpdate = new List<Account>();
7 for(Account a : scope){
8 a.Name = 'true';
9 a.NumberOfEmployees = 69;
10 accsToUpdate.add(a);
11 }
12 update accsToUpdate;
13 }
14 global void finish(Database.batchableContext info){
15 }
16}