拡張for文の真の実力を知り、反復処理を使いこなせ【改訂版】Eclipseではじめるプログラミング(20)(1/3 ページ)

これからプログラミングを学習したい方、Javaは難しそうでとっつきづらいという方のためのJavaプログラミング超入門連載です。最新のEclipseとJava 6を使い大幅に情報量を増やした、連載「Eclipseではじめるプログラミング」の改訂版となります

» 2010年12月21日 00時00分 公開
[小山博史株式会社ガリレオ]

Javaの反復処理の真の実力分かっていますか?

 連載第4回の「プログラミングの真骨頂! Javaで“反復処理”を覚える」では反復処理について、連載第5回の「データ集合を扱うのに便利なJavaの配列と拡張for文」では、拡張for文の基本について説明しました。

 反復処理には、いくつか種類がありましたが、実行したい処理の内容によって、どの方法を採用するかが決まりました。その中で、処理を繰り返す回数が決まっている場合によく利用されるfor文には「基本for文」「拡張for文」とがありました。これまでは、配列クラスインターフェイスといった文法事項を理解する前だったので、「拡張for文」については詳しく説明をしていませんでした。

 今回は、連載を通して必要な文法事項について理解してきたと思いますので、「拡張for文」について、少し詳しく見てみることにします。また、for文を使いこなすうえで重要な「continue」「break」といったキーワードについても説明します。

 EclipseでJavaプログラミングを始める準備がまだの方は、連載第1回の「Eclipse 3.4で超簡単Javaプログラミング基礎入門」で準備をしておいてください。

おさらい:拡張for文の書き方

 復習ですが、反復処理というのは、ある集合を表現するデータに対して、同じ処理を適用したいときによく利用する処理でした。反復処理の1つにfor文があり、基本for文と拡張for文がありました。拡張for文は、ある決まりきった基本for文の短縮形を提供するための単純な構文です。

 基本for文と拡張for文の文法について、まずは再確認をしておきましょう。

for (初期化部 ; 条件式; 更新部) 文
基本for文
for (型 繰り返し用変数名 : 集合式) 文
拡張for文

 ここで指定する「集合式」には、反復処理の対象とする「値の集合」を定義したオブジェクトを表す式を指定します。またその式の評価結果は、「java.lang.Iterableインターフェイスを実装したオブジェクト」「配列のインスタンス」のどちらかになる必要があります。

Iterator(イテレータ)を使った場合

 まず、「java.lang.Iterableインターフェイスを実装したオブジェクト」の例を見てみます。その前に、APIリファレンスの「java.lang.Iterableインターフェイス」を参照してみましょう。すると、このインターフェイスには「java.util.Iterator iterator()」というメソッドが宣言されていることが分かります。前回の「キュー構造をJavaで実装してジェネリック型を理解する」で説明したことを思い出してもらえば、このメソッドではジェネリック型を利用していることが分かります。

 このことから、java.lang.Iterableインターフェイスを実装するクラスは、必ずjava.util.Iterator型のオブジェクトを返却するiterator()というメソッドを持つということになります。いくつかの実装クラスがAPIリファレンスにありますが、ここでは、java.util.ArrayListクラスを使ってみましょう。次のようなプログラムを作ってみます。

package sample20;
 
public class Sample01 {
    public static void main(String[] args) {
        java.util.ArrayList<String> setExpression =
            new java.util.ArrayList<String>();
        setExpression.add("第1回");
        setExpression.add("第2回");
        setExpression.add("第3回");
        setExpression.add("第4回");
        setExpression.add("第5回");
        for (
           java.util.Iterator<String> it = setExpression.iterator();
           it.hasNext();
           // 更新部はなし
        ) {
            String element = it.next();
            System.out.println(element);
        }
    }
}
sample20/Sample01.java
第1回
第2回
第3回
第4回
第5回
実行結果

 setExpression内に保存されている各要素の値へアクセスする処理について、このようにjava.util.Iteratorインターフェイスを利用して反復処理を基本for文として記述できます。基本for文を使うと、java.util.Iteratorインターフェイスを使うための決まりきったコードを書く必要があります。

 同じ処理をするにしても、拡張for文を使うと、次のように書き表せて入力するコード量も少なくなり、見た目もすっきりとして、分かりやすくなります。実行結果は、sample20.Sample02クラスと同じになります。

package sample20;
 
public class Sample02{
    public static void main(String[] args) {
        java.util.ArrayList<String> setExpression =
            new java.util.ArrayList<String>();
        setExpression.add("第1回");
        setExpression.add("第2回");
        setExpression.add("第3回");
        setExpression.add("第4回");
        setExpression.add("第5回");
        for (String element : setExpression) {
            System.out.println(element);
        }
    }
}
sample20/Sample02.java

 「java.lang.Iterableインターフェイスを実装したオブジェクト」で表現した「値の集合」に対して、拡張for文を使用する利点は次のとおりです。

  • java.util.Iteratorのための変数を、わざわざ用意する必要がない
  • hasNextメソッドによるチェックをする必要がない

 一方、基本for文の方では、変数itがあるので、removeメソッドのような、集合に対して変更をするメソッドを使用できます。拡張for文では変数itの担う処理は明示的には見えないため、そういった処理はできない点には注意が必要です。

 「java.lang.Iterableインターフェイスを実装したオブジェクト」に対して拡張for文を使うと、「各要素へアクセスして反復処理をする」という意図が明確になり、集合に対しての変更はしていないということが分かります。

 なお、複数の集合に対して同時に処理を適用したい場合にも、拡張for文では対応できません。複雑な処理をしたい場合には、基本for文を使うことになります。

配列を使った場合

 参考までに、配列を使った場合のプログラムも見てみましょう。先ほどの例は、次のようになります。

package sample20;
 
public class Sample03 {
    public static void main(String[] args) {
        String[] setExpression = {
            "第1回", "第2回", "第3回", "第4回", "第5回"
        };
        for (int i=0; i < setExpression.length; i++) {
            String element = setExpression[i];
            System.out.println(element);
        }
    }
}
sample20/Sample03.java

 これは、次のような拡張for文で書き表せます。こちらも入力するコード量が少なくなり、見た目もすっきりとして、分かりやすくなります。

package sample20;
 
public class Sample04 {
    public static void main(String[] args) {
        String[] setExpression = {
            "第1回", "第2回", "第3回", "第4回", "第5回"
        };
        for (String element : setExpression) {
            System.out.println(element);
        }
    }
}
sample20/Sample04.java

 「配列のインスタンス」で表現した「値の集合」に対して、拡張for文を使用する利点は次のとおりです。

  • 配列の添え字の値を保存するための変数をわざわざ用意する必要がない
  • 配列の要素数のチェックをする必要がない

 ただし、ある添え字の要素を配列から削除したり、入れ替えをしたりするといった操作をしたい場合には、添え字の値が必要になるので、拡張for文よりは基本for文を使った方がいいでしょう。

 次ページでは、continue文・break文や“入れ子”の反復処理について解説します。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。