拡張for文の真の実力を知り、反復処理を使いこなせ:【改訂版】Eclipseではじめるプログラミング(20)(3/3 ページ)
これからプログラミングを学習したい方、Javaは難しそうでとっつきづらいという方のためのJavaプログラミング超入門連載です。最新のEclipseとJava 6を使い大幅に情報量を増やした、連載「Eclipseではじめるプログラミング」の改訂版となります
ラベル使って入れ子反復処理から一気に抜け出す
ラベルを使うことにより、文には名前を付けられます。ラベルを参照できるのは、break文とcontinue文だけで、これらと組み合わせることで、反復処理を分かりやすく記述できる場合があります。
ラベルは次のように、名前を付けたい文の前に書き「:」を付けます。1つの文に対しては、1つのラベルだけ付けられます。
ラベル名: 文
先ほどの変数blackCountを使った例では「blackCount == 64000」という判定を、2カ所でしていて冗長でした。実はラベルを使うと、sample20.Sample09クラスで「// loop x」とコメントを付けた位置で、両方の反復処理を終了できます。
次のように、外側のfor文に「LOOP_RGBARRAY」という名前を付けておけば、内側のfor文内で「blackCount == 64000」のときに、LOOP_RGBARRAYからbreakできます。for文のところのみ抜粋します。
int blackCount = 0;
LOOP_RGBARRAY:
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = rgbArray[y * width + x];
if (pixel == -16777216) {
blackCount++;
}
if (blackCount == 64000) {
System.out.println("break LOOP_RGBARRAY");
break LOOP_RGBARRAY;
}
Color c = new Color(pixel);
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
System.out.print("("+x+","+y+")="+pixel+" ");
}
System.out.println("");
}
ちなみに、「break LOOP_RGBARRAY;」のようなbreak文は「ラベル付きbreak(labeled break)」といい、「break;」のようにラベルが付いていないbreak文は「ラベルなしbreak(unlabeled break)」といいます。このように、ラベル付きbreakを使うと、入れ子となっている反復処理からの終了を簡単に実現できるようになります。
おまけ:画像データをHTMLで表現するプログラム
最後に、ちょっとしたサンプルプログラムを紹介しておきます。少し前に、ネット上で話題になりましたが、画像データはHTMLで表現できます。当然、Javaでも画像データからHTMLを生成するプログラムを作れます。これまでの連載の内容を理解していれば、詳細な説明は必要ないと思います。コードを眺めて理解してみてください。
package sample20;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import javax.imageio.ImageIO;
public class Sample11 {
public static void main(String[] args) throws Exception{
String fileName = "rgb.png";
File imageFile = new File(fileName);
BufferedImage image = ImageIO.read(imageFile);
int width = image.getWidth();
int height = image.getHeight();
int[] rgbArray = new int[width * height];
int offset = 0;
int scansize = width;
image.getRGB(0, 0, width, height, rgbArray, offset, scansize);
BufferedWriter writer = null;
try {
String encoding = "UTF-8";
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(new File(fileName + ".html")),
encoding));
writeHtml(rgbArray, width, height, writer);
} finally {
if (writer != null) {
writer.close();
}
}
}
private static void writeHtml(int[] rgbArray, int width, int height, BufferedWriter writer)
throws IOException {
writer.write("<html><head><meta http-equiv='content-type' ");
writer.write("content='text/html;charset=UTF-8'></head>");
writer.write("<body style='padding:0px; margin:0px;font-size:xx-small;'>");
writer.write("<pre style='overflow: auto; white-space: pre-wrap;'>\n");
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pixel = rgbArray[y * width + x];
Color c = new Color(pixel);
int r = c.getRed();
int g = c.getGreen();
int b = c.getBlue();
writer.write("<span style='background-color: #");
writer.write(toHex(r, g, b) + "; color: #");
writer.write(toHex(r, g, b) + ";");
writer.write("'>■</span>");
}
writer.write("\n");
}
writer.write("</pre></body></html>");
writer.flush();
}
private static String toHex(int r, int g, int b) {
StringBuilder sb = new StringBuilder();
sb.append(Integer.toHexString(r/16));
sb.append(Integer.toHexString(r%16));
sb.append(Integer.toHexString(g/16));
sb.append(Integer.toHexString(g%16));
sb.append(Integer.toHexString(b/16));
sb.append(Integer.toHexString(b%16));
return sb.toString();
}
}
拡張for文を使うと、分かりやすく見やすくなる
今回は、拡張for文について説明をしました。拡張for文は、java.lang.Iterableインターフェイスを実装したクラスのオブジェクトや、配列のインスタンスの各要素に対してアクセスしたい場合に非常に便利ですし、コードの意図も分かりやすくなり、見やすくなりますから、どんどん活用するようにしましょう。
また、continue文、break文についても説明しました。これらを使うことにより、反復処理の流れを分かりやすく記述できます。また、ラベル付きのcontinue文やbreak文を使うことにより、入れ子の反復処理における処理の流れを分かりやすく記述できる場合があることも説明しました。これらの文法もよく使われるものなので、理解しておくようにしましょう。
サンプルプログラムでは、画像処理についても簡単ながら説明をしました。こういうプログラムを作ってみると、画像データは色の付いた点の集まりだということが実感できるはずです。たまには、こういったプログラムを作成して遊んでみるのもいいのではないかと思います。
次回は、列挙型について説明をする予定です。今回作ったサンプルのソースコードはこちらからダウンロードできます。
筆者紹介
小山博史(こやま ひろし)
情報家電、コンピュータと教育の研究に従事する傍ら、オープンソースソフトウェア、Java技術の普及のための活動を行っている。長野県の地域コミュニティである、SSS(G)やbugs(J)の活動へも参加している。
著書に「基礎Java」(インプレス)、共著に「Javaコレクションフレームワーク」(ソフトバンククリエイティブ)、そのほかに雑誌執筆多数。
- Javaの例外処理で知らないと損する7つのテクニック
- プログラマの宿命! 例外とエラー処理を理解する
- いまさら聞けない「Javadoc」と「アノテーション」入門
- 7ステップで理解するJavaでの列挙型/enum使用法
- 拡張for文の真の実力を知り、反復処理を使いこなせ
- キュー構造をJavaで実装してジェネリック型を理解する
- 強く型付けされているJavaの理解に必修の“型変換”
- あなたの知らない、4つのマニアックなJava文法
- “ネスト”した型で始める軽量Javaプログラミング!?
- Javaは「抽象クラス」で実装を上手に再利用できる
- 再利用性の高いクラス作成に重要な“アクセス制御”
- “コンストラクタ”と初期化、本当に理解できてる?
- 継承やオーバーライドで簡単にクラスを“拡張”しよう
- 「static」でクラス共有の変数・メソッドを使いこなせ!
- Javaの実案件に必須のパッケージとインポートを知る
- プログラムを「変更」しやすくする“インターフェイス”
- Javaの参照型を文字列操作で理解して文法を総復習
- クラスの振る舞いを表すJavaの“メソッド”とは?
- 複雑なデータを表現できるクラスやフィールドって?
- データ集合を扱うのに便利なJavaの配列と拡張for文
- プログラミングの真骨頂! Javaで“反復処理”を覚える
- プログラミングの醍醐味! Javaで“条件式”を理解する
- Javaで一から理解するプログラムの変数と演算子
- Eclipse 3.4で超簡単Javaプログラミング基礎入門
Copyright © ITmedia, Inc. All Rights Reserved.