Iterator
概要
配列の場合は添字を使ってfor文を回してきたが,ArrayListのように配列も動的なサイズ可変が可能になり,かつ配列「オブジェクト」であることから,オブジェクト指向的な発想でfor文を回す必要が出てきた.
そこでIterator(イテレータ)というクラスを使う.
for(Iterator myIterator = myArrayList.iterator();
myIterator.hasNext();
){
クラス名 currentItem = myIterator.next();
currentItem.処理();
...
}
という形でfor文を回すと,添字を使わなくてもArrayListのサイズに応じて,ArrayListに入っている各オブジェクトインスタンスの処理を行うことが可能になる.
for文はfor(a ; b; c)
というセミコロンで区切られた3つの要素で記述されている.「aで初期化し,bがtrue
の時に,cを行いながら,処理を繰り返す」がその意味である.
Iteratorを使う場合,「初期化の時点でIteratorクラスのオブジェクトが生成され,そのオブジェクトのhasNext()
関数を呼んで,結果がtrue
だった場合(つまりまだ処理すべき要素が残っている場合),処理を繰り返す」形になっている.
つまりIteratorを使う場合,for文の3つ目の要素は指定する必要がないため「空」になる.(正確には「空にすることができる」)
コード例
BallModel.pdeは今までと共通なので省略.
// Processing_Iterator.pde
import java.util.ArrayList;
import java.util.Iterator;
import java.awt.Point;
import java.awt.Color;
ArrayList<BallModel> ballArray;
void setup(){
size(640, 480);
colorMode(RGB, 255);
frameRate(10);
ballArray = new ArrayList<BallModel>();
for(int i=0; i<10; i++)
ballArray.add(new BallModel(width, height));
}
void draw(){
fill(255, 255, 255, 60);
rect(0, 0, width, height);
// イテレータを使ったfor文
// イテレータはGenericsで作られているクラスなので,型指定が必要
for(Iterator<BallModel> ballIterator = ballArray.iterator();
ballIterator.hasNext();
){
// 次の要素(ここではBallModelクラスのオブジェクトインスタンス)を取得して
// currentBallというローカル変数に突っ込む
BallModel currentBall = ballIterator.next();
// あとは通常の処理
currentBall.updateParameters();
Point currentPoint = currentBall.getBallPosition();
Color currentColor = currentBall.getBallColor();
int currentSize = currentBall.getBallSize();
fill(currentColor.getRed(), currentColor.getGreen(), currentColor.getBlue());
ellipse((float)currentPoint.getX(), (float)currentPoint.getY(),
currentSize, currentSize);
}
}
拡張for文 (for-each)
Javaのような原理主義的オブジェクト指向プログラミングでは,上記のIteratorの方が「言語仕様的に美しい」.しかし,今後学ぶPythonやJavaScript,近年iOSアプリの開発に使われているSwift言語とそのAndroid開発版Kotlin言語など最近主流のLL(Lightweight Language, 軽量言語)では,「多少美しくなくても(多少不明瞭になっても)コード量が少ない方が便利」という考え方が一般的になっている.
そこでそのような言語で採用されている,簡単な記述でIteratorの処理を記述できる「拡張for文(for-each文)」がJavaにも導入された.
for(ArrayListに入ってるクラス名 currentItem: myArrayList){
currentitem.処理();
...
}
という記述だけで,Iteratorと同じことができる.
コード例
BallModel.pdeは共通なので省略.
// Processing_ExtendedFor.pde
import java.util.ArrayList;
import java.awt.Point;
import java.awt.Color;
ArrayList<BallModel> ballArray;
void setup(){
size(640, 480);
colorMode(RGB, 255);
frameRate(10);
ballArray = new ArrayList<BallModel>();
for(int i=0; i<10; i++)
ballArray.add(new BallModel(width, height));
}
void draw(){
fill(255, 255, 255, 60);
rect(0, 0, width, height);
// 拡張for文 BallModelクラスのcurrentBall変数にballArrayに格納されていた
// オブジェクトインスタンスを一つずつ入れていく,という意味
for(BallModel currentBall: ballArray){
// あとは普通の処理
currentBall.updateParameters();
Point currentPoint = currentBall.getBallPosition();
Color currentColor = currentBall.getBallColor();
int currentSize = currentBall.getBallSize();
fill(currentColor.getRed(), currentColor.getGreen(), currentColor.getBlue());
ellipse((float)currentPoint.getX(), (float)currentPoint.getY(),
currentSize, currentSize);
}
}