フィボナッチ数をStreamで扱ってみました。
サンプル
import java.math.BigInteger;
import java.util.stream.Stream;
/**
* フィボナッチ数をストリームで生成するサンプル
*/
public class Fibonacci {
/**
* 1000以上のフィボナッチ数を5件出力する。
*
* @param args
*/
public static void main(String[] args) {
fibonacciStream()
.filter(n -> n.compareTo(BigInteger.valueOf(1000l)) >= 0)
.limit(5l)
.forEach(System.out::println);
}
/**
* フィボナッチ数列のストリームを返す。
*
* @return フィボナッチ数列のストリーム
*/
public static Stream<BigInteger> fibonacciStream() {
return Stream.iterate(
new BigInteger[]{BigInteger.valueOf(1l), BigInteger.valueOf(1l)},
n -> {
BigInteger tmp = n[1];
n[1] = n[0].add(n[1]);
n[0] = tmp;
return n;
}
)
.map(n -> n[1])
;
}
}
解説
少しだけ解説します。
フィボナッチ数列
0, 1を起点に1, 2, 3, 5, 8, 13, 21, 34 …のように1つ前と2つ前の数値を合算したものが続いていく数列です。
Streamを使用せずに実装(whileループ)
int num1 = 0;
int num2 = 1;
int cnt = 0;
List<Integer> list = new ArrayList<Integer>();
while (++cnt <= 10) {
int tmp = num2;
num2 = num1 + num2;
num1 = tmp;
list.add(Integer.valueOf(num2));
}
System.out.println(list.toString());
// 出力結果は以下のとおり
// [1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Streamを使用して実装
無限ストリームを作成
Stream
.iterate(
new BigInteger[]{BigInteger.valueOf(1l), BigInteger.valueOf(1l)},
n -> {
BigInteger tmp = n[1];
n[1] = n[0].add(n[1]);
n[0] = tmp;
return n;
}
)
.map(n -> n[1])
;
iterateで無限ストリームを生成できます。
1つめのメソッドパラメータは最初の要素です。
2つめのメソッドパラメータは前の要素を元に新しい要素を返すための関数になります。
mapでBigInteger配列のフィボナッチ数を持つ要素のみ返すようにしています。
フィルタ、リミット、結果出力
Stream.iterate(
new BigInteger[]{BigInteger.valueOf(1l), BigInteger.valueOf(1l)},
n -> {
BigInteger tmp = n[1];
n[1] = n[0].add(n[1]);
n[0] = tmp;
return n;
}
)
.map(n -> n[1])
.filter(n -> n.compareTo(BigInteger.valueOf(1000)) > 0)
.limit(5)
.forEach(System.out::println);
filterで条件を指定し、limitで制限掛けて、forEachでSystem.out.printlnを実行して出力しています。