LoginSignup
2
2

More than 5 years have passed since last update.

RxJavaでフィボナッチ数列を出力する

Posted at

「RxJava フィボナッチ」でググるといくつか記事が出てきますが、あまりイケてるのがなかったので自分で書いてみました。

いくつかのオペレータを使うので、RxJavaの勉強には良さそうです。

値を保持するクラスを作成

今回は、1000より小さいフィボナッチ数列を出力します。

public class Fibonacci {
    /**
     * フィボナッチ数列の値
     */
    private final BehaviorSubject<Integer> value = BehaviorSubject.create();

    /**
     * 値をObservableで取得する
     */
    public Observable<Integer> getValue() {
        return value.asObservable();
    }

    /**
     * 値をセットする
     */
    public void setValue(int i) {
        value.onNext(i);
    }

    /**
     * 値の計算元となる2つのObservableをセットする
     */
    public void setSource(Observable<Integer> observable0, Observable<Integer> observable1) {
        Observable.zip(observable0, observable1, (i, j) -> i + j) // 値が来たら足し算する
                .filter(i -> i < 1000) // 1000以上では止まるようにする
                .subscribe(value::onNext); // 値を更新する
    }
}

呼び出し側

通常、subscribeを循環させると無限ループになってしまうのでやりませんが、ここではあえてそうすることで、値を次々に計算していきます。

public static void main(String[] args) {
    // 初期化
    Fibonacci a = new Fibonacci();
    Fibonacci b = new Fibonacci();
    Fibonacci c = new Fibonacci();

    // 値を出力する(※1)
    a.getValue().subscribe(System.out::println);
    b.getValue().subscribe(System.out::println);
    c.getValue().subscribe(System.out::println);

    // 値の計算元となる2つのObservableをセットする
    a.setSource(b.getValue(), c.getValue());
    b.setSource(c.getValue(), a.getValue().skip(1)); // (※2)
    c.setSource(a.getValue(), b.getValue());

    // 初期値をセットする
    a.setValue(0);
    b.setValue(1);
}

※1 必ず先に出力設定

値更新より前に出力設定をしないと、出力する前にどんどん値が更新されてしまいます。

※2 最初の値はスキップする

最初のbの計算では、aの初期値である0でなく、b+cが格納された後の2を使いたいので、1回だけスキップします。

(本当はここもスマートに書きたい)

出力

0
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987

考察

プログラムを書いていると、値を全て知っている人が現れるケースがしばしばあると思いますが、Subjectを使うことで、それぞれの項が自発的に値を計算し、それを伝搬している点で、責任が分散していていいかなと思いました。

似たような方法で、物理演算(波とか)もできるかなーとか思いました。

質問・ご意見があればお気軽にどうぞ! :raised_hands:

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2