繰り返しとはプログラム言語が、開発者が実現したい「処理」に
配列を順次読み取るように繰り返し処理を表現するために用意された最も基本的な構文の1つです。
繰り返し構文は、プログラム用では、「ループ文」とも呼びます。
ループ文を表現する構文は、for文、拡張for文(for-each),forEach文,while,while doがあります。
拡張for文はJava5からリリースされ、forEach文は、Java8からリリースされています。
forEachはJava8メニューからリリースする予定です。
for (
初期化式 ;
終了条件式;
ループ変数のインクリメント; ) {
ステートメント;
}
for文サンプル
String[] sampleData= { "カラム01" , "カラム02" , "カラム03" };
for( int i = 0 ; i < sampleData.length ; i++ ){
System.out.prinltn( "配列[" + i + "]=" sampleData[i] );
}
//この行はエラーになります。ループブロック外で変数iは既に消滅しています。
//System.out.prinltn( "ループ数:" + i );
初期化式は、ループ条件主にループ変数を初期化します。ループが始まると、一度実行されます。
終了条件式がfalseと評価されると、ループは終了します。
ループ変数のインクリメント式は、1回のループ処理(for文のブロック式)が終了する事に1回実行されます。
インクリメント式には、i++(インクリメント)及びi--(ディクリメント)が記述可能です。
初期化式内のループ変数は、プログラムの慣習で「i」で宣言します。2重、3重ループとなった場合には、「j」,「k」と変数を定義します。
初期化式で定義したループ変数は、for文のブロック範囲で有効な変数です。
ループ文が終了した場合にはそれ以後のステートメントでその変数は利用できません。
配列をループする際に一定の条件を満たした時に、ループ処理を終了させたい処理の場合には、ループ文内でbreak;句を利用します。
breakサンプル
String[] sampleData= { "カラム01" , "カラム02" , "" ,"カラム03" };
boolean errorFlg = false;
for( int i = 0 ; i < sampleData.length ; i++ ){
//値は、長さ1以上でなければならない
if( sampleData[i].legnth() == 0 ){
//エラー処理を実行してループを終了する。
dataValidError();
errorFlg = true;
break;
}
//ループ処理の主処理
doSomething();
}
配列内に定義されたString型の文字列に空文字を許可しないという要件があった場合には、上記例のようにbreak句でループ処理を終了できます。
配列をループする際に一定の条件を満たした時に、ループ処理内の後続処理を実行せずに
次の配列要素を実行したい場合には、ループ文内でcontinue;句を利用します。
continueサンプル
String[] sampleData= { "カラム01" , "カラム02" , "0" ,"カラム03" };
for( int i = 0 ; i < sampleData.length ; i++ ){
//値が「0」の場合はデフォルト値として処理をスルーする。
if( "0".equals( sampleData[i] ) ){
//値が0の場合には、初期値とみなし処理を実行しない。
continue;
}
//ループ処理の主処理
doSomething();
}
配列に配列が格納されていたり、List型にList型が格納されている場合に
ループ文ブロック内にループ文を定義した2重ループを記載できます。
2重ループサンプル
String[][] personTable = new String[2][5];
String[] oneRecode = {"山田","太郎","ヤマダ","タロウ","26","東京都"};
String[] towRecode = {"山田","花子","ヤマダ","ハナコ","17","大阪府"};
personTable[0] = oneRecode;
personTable[1] = towRecode;
//行全体のループ
for( int i = 0 ; i < personTable.length ; i++ ) {
String[] recode = personTable[i];
//カラムのループ
for( int j= 0 ; j < recode.length; j++ ) {
System.out.println( "配列[" + i + "]行目[" + j + "]カラム目データ=" + recode[j] );
//以下の記述形式で直接アクセス可能だが、保守性の面でNG
System.out.println( "配列[" + i + "]行目[" + j +"]カラム目データ=" + personTable[i][j] );
//doSomething();
}
}
2重ループ内では personalTable[i][j]というように変数recodeを定義せずに記述できますが、
経験に依存した記述形式はループ変数i,jを取り間違えるようなミスを誘発します。
記述行数が増えても次のループの可読性が増すように 全体のループで参照している配列を上記のように変数で定義します。
2重ループ利用時にbreak句及びcontinueを利用した場合に、2重ループ内から全体のループのbreak,continueを実施できるようになります。
全体のループと2重ループのそれぞれのfor文にラベルを付与し、break及びcontinue ループラベルを指定します。
ループラベルサンプル
String[][] personTable = new String[2][5];
String[] oneRecode = {"山田","太郎","ヤマダ","タロウ","26","東京都"};
String[] towRecode = {"山田","花子","ヤマダ","ハナコ","17","大阪府"};
personTable[0] = oneRecode;
personTable[1] = towRecode;
List<String[]> errorRecode = new ArrayList<String[]>();
//行全体のループ
recodeLoop:for( int i = 0 ; i < personTable.length ; i++ ) {
String[] recode = personTable[i];
//カラムのループ
columnLoop:for( int j= 0 ; j < recode.length; j++ ) {
if( j == 4) {
if( Integer.valueOf( recode[4]).intValue() < 18 ){
errorRecode.add( recode );
continue recodeLoop;
}
}
//innerLoopSomething;
}
//outerLoopSomething;
}
上記のように ループラベルを設定することでbreak及びcontinueが、
2重ループ側から全体のループのをbreak又はcontinueを実現することができます。
Java5よりfor文を拡張した「拡張for文」が利用できるようになりました。
拡張for文がリリースされた目的は、「for文」の冗長な構文( int i = i; i < hoge.legnth ; i++)を簡潔に表現することが目的です。
拡張for文は、配列形式またはCollectionクラス(Collectionを継承したクラス)に適応できます。
for (
配列型 変数名:
配列またはCollectionオブジェクト ) {
//ループ内ステートメント;
doSomething();
}
拡張for文サンプル
List<String> errorMsgList = new ArrayList<String>();
errorMsgList.add( new String( "this is one message." ) ) );
errorMsgList.add( new String( "this is tow message." ) ) );
errorMsgList.add( new String( "this is third message." ) ) );
int counter = 0;
for( String errorMsg : errorMsgList) {
System.out.println( errorMsg );
counter++;
}
上記例のようにループ位置(counter)が必要な場合の実装例を記載しています。
但し、このようにループ位置を必要とするループ文は基本のfor構文を利用することが望ましいです。