Java のReactive Extensions (.NET) に相当するものはありますか?
Rx (リアクティブ拡張機能) について
Rx は、監視可能なコレクションを使用して、非同期およびイベント ベースのプログラムを作成するためのライブラリです。
JBOSS のDroolsなどのルール エンジンは知っていますが、Microsoft .NET のアプローチに近い方法は他にありますか?
Java のReactive Extensions (.NET) に相当するものはありますか?
Rx (リアクティブ拡張機能) について
Rx は、監視可能なコレクションを使用して、非同期およびイベント ベースのプログラムを作成するためのライブラリです。
JBOSS のDroolsなどのルール エンジンは知っていますが、Microsoft .NET のアプローチに近い方法は他にありますか?
このNetFlixブログ投稿によると、彼らはRxをJavaに移植しました。まだ利用できないようですが、社内で開発したツールなどをオープンソースとしてリリースしてきた歴史があるので、やがてリリースされると思います。
私はそれを知りません - 率直に言って、これほどきちんとした方法で行うのは難しいでしょう。スレッド側は問題ありません。スレッド化に関しては、Java は完全に機能しますが、現時点では、この言語は適切な機能をサポートしていません。
LINQ の優れた設計機能の 1 つは、すべてがインターフェイスに基づいており、拡張メソッドを使用して機能を追加することです。これにより、コードを流暢に読むことができます-次のように書く必要があると想像してください:
IObservable<int> = Observable.Select(
Observable.Where(
source, x => x.SomeCondition)
x => x.SomeProjection);
イク。拡張メソッドははるかに優雅です:
IObservable<int> = source.Where(x => x.SomeCondition)
.Select(x => x.SomeProjection);
現在、Java バージョンは代わりに抽象基本クラスに基づくことができますが、それではエレガンスの一部が失われます。
次は、ラムダ式とメソッド グループの変換です。これらは、一般的に LINQ の基本です。Java で最も近いもの (匿名内部クラス) は、C# でラムダ式を使用するすべての場所で使用するにはあまりにも醜いです。
基本的に、Rx の Java バージョンは実行可能ですが、C# バージョンほどエレガントではありません。これがおそらく、私の知る限り、それが行われていない理由です。Java 用の「非同期駆動型」ライブラリは他にもあるかもしれませんが、それらが Rx ほど包括的できちんとしたものである可能性は低いです。
Java 7の変更により、これがより実現可能になる可能性があります。私の知る限り、拡張メソッドは導入されていませんが、ラムダ構文が最終的に問題ない場合は、抽象基本クラスのバージョンが合理的です...
それでも興味があるなら、私は最近Javaライブラリに取り組んでおり、これはリアクティブ側とインタラクティブ側でもほとんどのRxオペレータを提供しています。
.NETほど良くないことは間違いありません。Java には拡張メソッドや関数型がないため、静的メソッドと内部クラスを介してすべてを呼び出す必要があります。.NET の場合:
Observable.Range(0, 10).SelectMany(
o => Observable.Range(0, o)
).Run(Console.WriteLine);
私のライブラリ:
Reactive.run(
Reactive.selectMany(
Reactive.range(0, 10),
new Func1<Observable<Integer>, Integer>() {
public Observable<Integer> invoke(Integer param1) {
return Reactive.range(0, param1);
}
}
), Reactive.println());
Interactive.run(
Interactive.selectMany(
Interactive.range(0, 10),
new Func1<Iterable<Integer>, Integer>() {
public Iterable<Integer> invoke(Integer param1) {
return Interactive.range(0, param1);
}
}
), Interactive.println());
ラムダには Func0、Func1、Func2 型を使用し、登録解除には Closeable 型を使用します。Java がファースト クラスの関数市民を取得すると、これらの FuncX 型を簡単に置き換えることができます。Closeable は、Java 7 の try-with-resources 拡張機能で使用できます。3 番目の醜さは、さまざまな場所での弱い型推論によるものです。
RxJava (Netflix によって移植された RX) は、 https ://github.com/ReactiveX/RxJava で利用可能で安定しています。
Java 8 のラムダ構文でもうまく機能します。あなたはそのようなことをすることができます:
Observable
.from(Arrays.asList(1, 2, 3, 4, 5))
.filter(val -> val % 2 == 0)
.map(val -> val * val)
.scan(0, (prev, curr) -> prev + curr)
.subscribe(System.out::println)
かなりクールな?
ActionScript 3 で記述されたraix ( wiki ) が Java 7 に到着したら、Java 7 に移植することを検討するかもしれません。プロジェクト (私自身) はオープンソースであり、互換性を確保するためにフレームワークの .NET バージョンのブラックボックス単体テストが含まれています。
Java と同様に、AS3 は拡張メソッドもラムダ式もサポートしていないため、実装は類似している可能性があります。そうは言っても、AVM はスレッドをサポートしていないため、RxA にはロック コードがないため、競合状態に注意する必要があります。
Reactive Streams 仕様を実装する Project Reactor を使用できます。Mono と Flux の 2 つの Publisher インターフェイスを提供します。
Mono は 0 個または 1 個のアイテムを発行できますが、Flux は onNext シグナルを介して 0…n 個のアイテムを発行できます。
Project Reactor をカバーする Java でのリアクティブ プログラミングに関する優れたチュートリアルは、こちらです。