Observableのメソッド
ObservableのJavaDocを見るとわかるのですが、Observableのメソッドの多くはObservableを返します。これはObservableの多くのメソッドがデータのフィルタや加工を行うメソッドだからです。これらのメソッドが呼ばれると、元のObservableからデータのフィルタや加工を行った新しいObservableが生成されます。そして、新規に生成されたObservableは元のObservableが全ての処理を行ってから生成されるのではなく、メソッドを呼んだタイミングで生成され、元のObservableが各データを通知するタイミングで変更されたデータを通知します。
この特性よりメソッドを数珠つなぎ(メソッドチェーン)にして元のObservableから必要なデータを通知する新しいObservableを生成することができます。これはJava 8のStreamを使ったことがある人だとイメージがしやすいかもしれません。
例えば、次のサンプルでは1から10までの数値を通知するObservableからデータを偶数のみに絞り、そのデータを括弧でくくり"[データ]"の文字列に変換したものを通知するObservableを生成しています。このサンプルでは、まだ説明していないメソッドやラムダ式で記述しているところがありますが、ここでは詳細については気にしないで、メソッドチェーンを使って最終的なObservableを生成していることに注目してください。
Observable<String> observable =
Observable.range(1, 10) // ① 1~10までの数値を通知するObservable
.filter(value -> value % 2 == 0) // ② 偶数のみにする
.map(value -> "[" + value + "]"); // ③ "[データ]"の文字列にする
// 購読開始
observable.subscribe(System.out::println);
これを実行すると次の結果になります。
[2] [4] [6] [8] [10]
これを段階的に説明すると、まず①ではrangeメソッドを使って1から始まるデータを10個まで通知するObservableを生成しています。Observableが通知するデータは次のものになります。
1、2、3、4、5、6、7、8、9、10
次に②で受け取ったデータをvalue % 2 == 0で判定を行い、偶数のもののみにフィルタをしています。ここで生成されるObservableが通知するデータは次のものになります。
2、4、6、8、10
最後に③で受け取ったデータを"[" + value + "]"でデータの両端に括弧をつけた文字列に変換しています。ここで生成されるObservableが通知するデータは次のものになります。
"[2]"、"[4]"、"[6]"、"[8]"、"[10]"
このデータをObserverが受け取ることで実行結果の内容が出力されます。
また、関数型インタフェースを実装する際の注意点として、受け取ったデータ(各関数型インタフェースで引数として受け取るデータ)に対し、そのデータの状態を変えたり、Observableの外部の状態を変えたりするような副作用を起こさないようにしなければなりません。関数型インタフェースの実装の原則として、関数型インタフェースに対し引数に同じ値が与えられたら同じ結果を毎回返し、かつ引数やObservableの外部に対して何も変えないようになっています。そのため、Observable内で扱うデータは基本データ型か生成後にオブジェクトの中身が変わらないイミュータブル(Immutable)なオブジェクトを使うことが好ましいです。
