Javaの拡張for文がとても便利
自作クラスもイテレータとして与えられることを知ったので自分メモ
(基礎すぎるからかあまり記事がなかった気がする....)
使い方
package fibonacci;
class Main{
public static void main(String[] args){
for(int i:Fibonacci.to(10)){
System.out.println(i);
}
}
}
拡張for文の説明
for(イテレータが返してくれる値を格納する変数の定義: イテレータ)
では実際のFibonacciクラスの実装
package fibonacci;
import java.util.Iterator;
public class Fibonacci implements Iterator<Integer>, Iterable<Integer>{
private int num1;
private int num2;
private int num3;
private int count;
private int to;
public Fibonacci(int to){
this.num1 = 0;
this.num2 = 1;
this.to = to;
this.count = -1;
}
public static Iterable<Integer> to(int num){
return new Fibonacci(num);
}
@Override
public Iterator<Integer> iterator(){
return this;
}
@Override
public boolean hasNext(){
if(count < to){
count++;
return true;
}
return false;
}
@Override
public Integer next(){
if(count < 2){
return count;
}
num3 = num1 + num2;
remove();
return num3;
}
}
まずは実装しているインターフェース
IterableインターフェースとIteratorインターフェース
先程拡張for文の:(コロン)の後はイテレータを指定すると書きましたが、少し違うようですね。
拡張for文で使えるようにするにはIterableインターフェースを実装しているクラスである必要があります。
IterableインターフェースのiteratorメソッドがIteratorのオブジェクトを返すのでそいつが1つづつ返す値をfor文の中でループさせる感じですかね。
Iteratorインターフェースで実装する必要があるメソッドは
boolean hasNext()
T next()
とりあえずこいつらを実装すればforで回せます。
両方共その名の通りです。
boolean hasNext()
は「次の値があるかないか」を判定するメソッド
T next()
はT型の次の値を返すメソッド
拡張forでIterableを実装したクラスが指定されるとまずは
Iteratorを返すメソッド(今回の場合はto(int num)
)が呼ばれる。
boolean hasNext()
がtrue
を返した場合T next()
が実行される感じですね。
あと気になったことはvoid remove()
とvoid forEachRemaining(Consumer<? super E> action)
メソッド。
両方共default句が付いているので実装しなくてもエラーにはなりませんし、今回のケースに限っては困りません。(わかる方がお読みになりましたら是非教えていただきたいです)
実行例
% java Main
0
1
1
2
3
5
8
13
21
34
55