Linqの機能を提供することに近いJavaのライブラリはありますか?
Linqの機能を提供することに近いJavaのライブラリはありますか?
回答:
完全なLINQクエリ構文を取得するには、新しいキーワードと構文構造をサポートする言語仕様とコンパイラの更新が必要になります。ここではほとんどの読者をはるかに超えています。
C#のように見え、動作するJavaでLinqのようなメソッドチェーン構文を取得するには、Javaでサポートされていないものが2つ必要です。拡張メソッド(インスタンスメソッドであるかのようにインスタンスに適用できる静的メソッド)、およびラムダ式(匿名デリゲート)。ただし、少し余分なコーディングの冗長性が必要な場合は、これら2つを既存のJava構造で偽装することができます。Javaで特に素晴らしいと思うことの1つは、匿名のインターフェイス実装を作成できることです。必要な各メソッドシグネチャのインターフェイスがある場合、基本的に単純な匿名デリゲートを許可する単一の純粋な関数を持つインターフェイスに適用されます。
そのため、LinqのIEnumerable(Javaheadsで反復可能)側は、メソッドチェーンとして、Javaで近似できる必要があります。基本的にモナドを制御する流fluentなインターフェースとして実装します。LinqIterable
Iterableを実装するaのようなクラスが必要です:
そのため、次のようなステートメントを許可する「流れるような」ライブラリをおそらく定義できます。
Map<String, Integer> results = Linq.FromIterable(sourceList)
.Where(new Predicate{public bool Op(SomeStruct in){return in.SomeString == "criteria";}})
.OrderBy(new Func{public String Op(SomeStruct in){return in.SomeOtherString;}})
.Select(new Func{public SomeOtherStruct Op(SomeStruct in){return new SomeOtherStruct(in.SomeOtherString, in.SomeInt);}})
.ToMap(new Func{public String Op(SomeOtherStruct in){return in.StringField;}},
new Func{public Integer Op(SomeOtherStruct in){return in.IntField;}});
実際のライブラリの作成は、インターネットに関するQ&Aの回答の範囲をはるかに超えた演習です。簡単ではなく、可能だと言ったばかりです。
式ツリーはロケット科学ではありませんが、この分野で.NETが持つものを実装することは重要なプロジェクトです。式ツリーを構築する機能が必要なだけでなく、発行されたバイトコードを使用して、このツリーをその場で「コンパイル」できる必要があります。Javaのリフレクションがこれほど強力かどうかはわかりません。
見る:
Scalaの.NETポートを使用します。これにより、明らかにLINQを含む.NETのすべてに完全にネイティブアクセスできます。
できない場合は、functionjavaやlambdajなどのライブラリを使用してみることはできますが、実際にはLINQには近づきません。
ライブラリのリストにguavaを追加すると、LINQの機能の一部を実現できます。
しかし、他の人が指摘したように、純粋なJavaには同等のものはありません。
Clojureで記述されたSQLクエリ用のDSLであるKormaを使用できます。
構文はかなりきれいです:
(select user
(with address)
(fields :firstName :lastName :address.state)
(where {:email "korma@sqlkorma.com"}))
関連するClojureライブラリをインポートし、通常のClojure / Java相互運用を使用するだけで、Javaからこれを簡単に呼び出すことができます。
linqを模倣するjavaのネイティブ機能はありません。ただし、同じ機能を提供するAPIがいくつかあります。
たとえば、このブログ投稿には、linqを複製するためのカスタムjarがあります。
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
そして、これは投稿からのAPIの使用例です:
のリストで表される名前とIDを含むAnimalオブジェクトがあるとしますanimals
。リストから「o」を含むすべての動物名を取得したい場合animals
、次のクエリを書くことができます
from(animals).where("getName", contains("o")).all();
where("getName", ...)
。