実務で使われるプログラム、特にバッチ処理では、ループ処理は頻出です。
ループ処理には、良く使われるパターンがいくつかあります。
そのパターンを覚えておけば、既存のソースコードの理解がスムーズになります。
今回の記事では、実務で良く使われるループ処理のパターンを挙げていきます。
1.二重ループ
ループの内側にループがあるというのは良くあるパターンです。
javaでサンプルを書くと以下のようなパターンです。
public class Main {
public static void main (String[ ] args){
int arraySizeX = 3;
int arraySizeY = 3;
int array[ ][ ] = new int[arraySizeX][arraySizeY];
boolean endFlag = false;
array[0][0] = 1;
array[0][1] = 2;
array[0][2] = 3;
array[1][0] = 4;
array[1][1] = 5;
array[1][2] = 6;
array[2][0] = 7;
array[2][1] = 8;
array[2][2] = 9;
int i = 0;
while (!endFlag) {
int j = 0;
while (!endFlag && j < arraySizeY) {
System.out.println(array[i][j]);
if (array[i][j] == 5) {
endFlag = true;
}
j++;
}
i++;
if (i == arraySizeX) {
endFlag = true;
}
}
}
}
実行結果は
1
2
3
4
5
です。
何をしているのかと言うと、
・2次元配列に格納した値を順番に取り出している
・ただし、5を取り出したらその時点で処理を終了する
ということをしています。
(実務では、1次元目が親項目、2次元目が子項目のことが多いです)
このパターンのループの場合、原則として、内側のループの終了条件は外側のループの終了条件を内包しています。
今回の例で言うと、
・内側のループの終了条件…!endFlag && j < arraySizeY
・外側のループの終了条件…!endFlag
となっています。
このような場合、内側のループにしかない終了条件に着目すると、それぞれのループで何をしているのか把握しやすくなります。
今回の例で言うと、内側のループにしかない終了条件として「j < arraySizeY」があります。
この終了条件に着目することで、内側のループでは2次元目の配列を順番に読んでいる、ということを把握することができます。
2.リトライ処理
タイミングによって失敗する可能性がある処理を行う場合、失敗してもすぐに異常終了しないように、その処理が失敗した際にリトライをかける制御を入れることがあります。
例えば、通信やデータベースアクセス等で良く使われる制御です。
フローチャートで言うと以下のようになります。
「処理が失敗した時だけループを継続する」というロジックになっていたら、このパターンである可能性が高いです。
なお、今回のフローチャートでは省略していますが、無限ループで負荷がかからないように、ループ時にスリープを入れたり、ループ回数を設定したりすることも多いです。
3.先読みRead
レコードの中身を見てループ継続条件を判断する場合は、1レコード目のみループの前に先読みして、2レコード目以降はループの中で読み込む、ということをします。
フローチャートで言うと以下のようになります。
(EOFの場合の処理は省略しています)
派生パターンとしては、コントロールブレイクやマッチング処理があります。
詳しくは以下のページを参照してください。
・コントロールブレイク
・マッチング処理
なお、ファイルの場合はReadですが、SQLのカーソルの場合はFetchです。どちらにしても制御としては同じです。