Linqに相当する最高のJavaは何ですか?[閉まっている]


17

Linqの機能を提供することに近いJavaのライブラリはありますか?


1
「LINQの機能」ではなく「LINQの構文」を意味すると思います。同じ機能を提供する多くのライブラリがあります:
mikera

Javaに相当するものは、おそらくGroovyです。にもかかわらず型の安全性を失うことを犠牲にして
ブヨ

回答:


20

完全なLINQクエリ構文を取得するには、新しいキーワードと構文構造をサポートする言語仕様とコンパイラの更新が必要になります。ここではほとんどの読者をはるかに超えています。

C#のように見え、動作するJavaでLinqのようなメソッドチェーン構文を取得するには、Javaでサポートされていないものが2つ必要です。拡張メソッド(インスタンスメソッドであるかのようにインスタンスに適用できる静的メソッド)、およびラムダ式(匿名デリゲート)。ただし、少し余分なコーディングの冗長性が必要な場合は、これら2つを既存のJava構造で偽装することができます。Javaで特に素晴らしいと思うことの1つは、匿名のインターフェイス実装を作成できることです。必要な各メソッドシグネチャのインターフェイスがある場合、基本的に単純な匿名デリゲートを許可する単一の純粋な関数を持つインターフェイスに適用されます。

そのため、LinqのIEnumerable(Javaheadsで反復可能)側は、メソッドチェーンとして、Javaで近似できる必要があります。基本的にモナドを制御する流fluentなインターフェースとして実装します。LinqIterableIterableを実装するaのようなクラスが必要です:

  • Iterable入力をLinqIterableインスタンスに変換できます
  • フィルタリング、グループ化、連結、交差、順序付けなどの単機能インターフェイスを受け入れ、新しいLinqIterablesを生成する基本的なリスト処理のためのメソッドがあり、これらのメソッドのチェーンを可能にします。
  • LinqIterableを変換して、ToList、ToArray、ToMapなどの「具体的な」オブジェクトに戻すメソッドがあります。

そのため、次のようなステートメントを許可する「流れるような」ライブラリをおそらく定義できます。

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のリフレクションがこれほど強力かどうかはわかりません。


2
面白いことに、Java 8には十分な拡張メソッドとラムダ式があります。おそらくLINQが近づいていますか?
lxs

4
拡張メソッドとラムダがある場合は、.NETのLinqの「列挙可能な」側を大きな労力なしで使用できます。先ほど言ったように、Linqクエリを作成するキーワードを許可するにはJava仕様を変更する必要がありますが、正直なところ日常のLinqの使用では、それほど簡単ではないクエリはあまり見つかりませんでしたメソッドチェーンとして表され、コンパイラはほとんどLinq構文をメソッドチェーンに変換します(ほとんどのクエリとチェーン間で1:1を変換できるVSプラグインが存在します)。次の本当の足がかりは、式ツリー(Queryable Linq)です。
キース

8

見る:


1
これらの各リソースの内容を少し拡大してみてください。また、質問に対する回答としてこれらのリソースを推奨するのはなぜですか。Stack Exchange では「リンクのみの回答」は歓迎されません
-gnat

うーん、それはこのQがすでに回答された場合だと思います-複製として修正されるべきですか?
マルティンヴェルブルク

1
@MartijnVerburg-質問をサイト間で重複としてマークすることはできません。答えは本当に独立できる必要があります。
ChrisF

編集しました。うまくいけば、もう少し役立つと思います。
マルティンヴェルブルク

5

いいえ。Linqには、Javaが持っていない多くの言語機能が必要です。


4
Javaにはジェネリックがあります。
ジョナス

6
@Jonas:それは本当ですが、実際にLINQをサポートするのに十分な強度があるかどうかは別問題です。
-DeadMG

2
@DeadMGはまだ、Javaにはジェネリックがあります。
マフムードホッサム

ジェネリック医薬品への参照を削除するために編集
トムスクワイアズ

3

ここで説明する理由によりScalaを使用します

Scalaの.NETポートを使用します。これにより、明らかにLINQを含む.NETのすべてに完全にネイティブアクセスできます。

できない場合は、functionjavalambdajなどのライブラリを使用してみることはできますが、実際にはLINQには近づきません。


1
ScalaにはライブラリのないLinqのようなものは含まれていません。
ジョナス

1
@ジョナス:だから?JavaにはライブラリにLinqのようなものは含まれていません。
back2dos

@ back2dos:はい、だからこそ図書館で答えなければなりません。
ジョナス

1
@Jonas:Scalaの標準ライブラリはLINQに似ています。または逆に、LINQはC#の関数型プログラミングイディオムのセットにすぎません。詳細はこちら
-back2dos

@ back2dos:すばらしいリンクをありがとう、私はそれを自由に取り入れました。
ランデイ

2

ライブラリのリストにguavaを追加すると、LINQの機能の一部を実現できます。

しかし、他の人が指摘したように、純粋なJavaには同等のものはありません。


それが何をするのか、そして尋ねられた質問に答えるのになぜそれをお勧めするのか、もっと説明してもらえますか?Stack Exchange では「リンクのみの回答」は歓迎されません
-gnat

2

Clojureで記述されたSQLクエリ用のDSLであるKormaを使用できます。

構文はかなりきれいです:

(select user
  (with address)
  (fields :firstName :lastName :address.state)
  (where {:email "korma@sqlkorma.com"}))

関連するClojureライブラリをインポートし、通常のClojure / Java相互運用を使用するだけで、Javaからこれを簡単に呼び出すことができます。


だから、これはオブジェクト上のLINQではなく、SQL上のLinqをエミュレートしますよね?
ジョブ

@ジョブ:はい、SQL用に設計されています。オブジェクトにも拡張/適応できない理由は見当たりませんが。
ミケラ

2

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();

ブログ投稿で参照されている他の2つのAPIがあります: lambdaJjLinq


1
静的型チェックとクラスメンバの存在のチェックの両方を失うことは、のような呼び出しを呼び出すための少し急な価格になるのではないかと心配していますwhere("getName", ...)
9000
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.