Apa yang setara dengan Java terbaik untuk Linq? [Tutup]

17

Apakah ada perpustakaan di Jawa yang hampir menyediakan fungsionalitas Linq?

rdasxy
sumber
1
Saya kira maksud Anda "sintaks LINQ" daripada "fungsi LINQ". Ada banyak perpustakaan yang menyediakan fungsionalitas yang sama :-)
mikera
Setara dengan Jawa kemungkinan besar adalah Groovy . Dengan mengorbankan kehilangan jenis keamanan sekalipun
nyamuk

Jawaban:

20

Untuk mendapatkan sintaks kueri LINQ lengkap, Anda perlu memperbarui spesifikasi bahasa dan kompiler yang mendukung kata kunci dan struktur sintaksis baru. Ini jauh melampaui kebanyakan pembaca di sini.

Untuk mendapatkan sintaks rantai-metode Linq seperti di Jawa yang terlihat dan berfungsi seperti apa yang ada di C #, Anda memerlukan dua hal yang tidak didukung Java; metode ekstensi (metode statis yang dapat diterapkan ke instance seolah-olah itu adalah metode instance), dan ekspresi lambda (delegasi anonim). Namun, keduanya dapat dipalsukan dengan konstruk Java yang ada, jika Anda bersedia mengeluarkan sedikit tambahan kata sandi pengkodean. Satu hal yang saya temukan sangat mengagumkan tentang Java adalah kemampuan untuk membuat implementasi antarmuka anonim; diterapkan pada antarmuka dengan fungsi murni tunggal, yang pada dasarnya memungkinkan delegasi anonim sederhana, asalkan Anda memiliki antarmuka untuk setiap metode tanda tangan yang Anda perlukan.

Jadi, sisi IEnumerable (Iterable for the Javaheads) dari Linq, sebagai rantai metode, harus dapat diperkirakan di Jawa; Anda pada dasarnya akan mengimplementasikannya sebagai antarmuka yang lancar yang mengontrol monad. Anda memerlukan kelas seperti LinqIterable, mengimplementasikan Iterable, yang:

  • dapat mengonversi input Iterable apa pun menjadi instance LinqIterable
  • memiliki metode untuk pemrosesan daftar dasar, seperti pemfilteran, pengelompokan, penggabungan, persimpangan, pemesanan, dll yang menerima antarmuka fungsi tunggal dan menghasilkan LinqIterables baru, memungkinkan rangkaian metode ini, semoga dengan cara "malas".
  • memiliki metode untuk mengubah kembali LinqIterable menjadi objek "konkret" seperti ToList, ToArray, ToMap, dll

Jadi, Anda mungkin bisa mendefinisikan pustaka "fasih" yang memungkinkan pernyataan seperti:

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

Pembuatan perpustakaan yang sebenarnya adalah latihan yang jauh melampaui lingkup jawaban di T&J internet. Saya hanya mengatakan itu mungkin, tidak mudah.

Pohon ekspresi bukanlah ilmu roket, tetapi itu akan menjadi proyek yang signifikan untuk mengimplementasikan apa yang dimiliki oleh .NET di bidang ini; Anda tidak hanya memerlukan kemampuan untuk membangun pohon ekspresi, Anda harus dapat "mengkompilasi" pohon ini dengan cepat menggunakan bytecodes yang dipancarkan; Saya tidak tahu apakah refleksi Java cukup kuat.

KeithS
sumber
2
Lucunya metode ekstensi dan ekspresi lambda keduanya di Jawa 8. Mungkin LINQ sedang dalam perjalanan?
Lxs
4
Nah jika Anda memiliki metode ekstensi dan lambda, Anda memiliki sisi "Enumerable" dari. Linq .NET tanpa upaya besar. Masih akan, seperti yang saya katakan, memerlukan perubahan ke spesifikasi Java untuk memungkinkan kata kunci yang membuat kueri Linq, tetapi jujur ​​dalam penggunaan Linq sehari-hari saya belum menemukan terlalu banyak kueri yang tidak semudah itu. dinyatakan sebagai rantai metode, dan kompiler cukup banyak mengubah sintaks Linq ke rantai metode (ada plugin VS yang dapat mengkonversi 1: 1 antara sebagian besar kueri dan rantai). Batu loncatan nyata berikutnya adalah pohon ekspresi (Queryable Linq).
KeithS
8

Lihat:

Martijn Verburg
sumber
1
maukah Anda memperluas sedikit tentang apa yang masing-masing sumber daya miliki dan mengapa Anda merekomendasikan ini sebagai menjawab pertanyaan yang diajukan? "Jawaban khusus tautan" tidak diterima di Stack Exchange
agas
Hmm, saya kira itu adalah kasus bahwa Q ini sudah dijawab - harus diubah sebagai duplikat?
Martijn Verburg
1
@ MartijnVerburg - kami tidak dapat menandai pertanyaan sebagai duplikat di seluruh situs. Jawaban benar-benar harus bisa berdiri sendiri.
ChrisF
Diedit, semoga sedikit lebih bermanfaat sekarang.
Martijn Verburg
5

Tidak. Linq membutuhkan banyak fitur bahasa yang hanya dimiliki oleh Java

Tom Squires
sumber
4
Java memang memiliki obat generik.
Jonas
6
@Jonas: Itu benar, tetapi apakah mereka sebenarnya cukup kuat untuk mendukung LINQ adalah masalah lain.
DeadMG
2
@DeadMG masih, Java memang memiliki obat generik.
Mahmoud Hossam
Diedit untuk menghapus referensi ke obat generik
Tom Squires
3

Gunakan Scala , untuk alasan yang dijelaskan di sini :

gunakan port .NET dari Scala. Ini memberi Anda akses asli penuh ke segala sesuatu di. NET, yang jelas termasuk LINQ.

Jika tidak bisa, Anda dapat mencoba menggunakan libs seperti functionjava atau lambdaj , tetapi Anda tidak akan benar-benar dekat dengan LINQ.

Landei
sumber
1
Scala tidak memasukkan sesuatu seperti Linq tanpa perpustakaan.
Jonas
1
@Jonas: Jadi? Java tidak menyertakan Linq dengan pustaka.
back2dos
@ back2dos: Ya, itu sebabnya Anda harus menjawab dengan perpustakaan.
Jonas
1
@Jonas: Pustaka standar Scala seperti LINQ. Atau sebaliknya: LINQ hanyalah sekumpulan idiom pemrograman fungsional untuk C #. Lebih lanjut tentang itu di sini .
back2dos
@ back2dos: Terima kasih atas tautannya, saya mengambil kebebasan untuk memasukkannya.
Landei
2

Saya akan menambahkan jambu ke daftar perpustakaan yang dapat membantu Anda mencapai beberapa hal yang dilakukan LINQ.

Tetapi seperti yang telah ditunjukkan orang lain, tidak ada padanan di Jawa murni.

Otto Allmendinger
sumber
maukah Anda menjelaskan lebih lanjut tentang apa yang dilakukannya dan mengapa Anda merekomendasikannya untuk menjawab pertanyaan yang diajukan? "Jawaban khusus tautan" tidak diterima di Stack Exchange
agas
2

Anda bisa menggunakan Korma , sebuah DSL untuk query SQL yang ditulis dalam Clojure.

Sintaksnya cukup rapi:

(select user
  (with address)
  (fields :firstName :lastName :address.state)
  (where {:email "[email protected]"}))

Anda dapat memanggil ini dengan mudah dari Jawa dengan mengimpor pustaka Clojure yang relevan dan hanya menggunakan interop Clojure / Java normal.

mikera
sumber
Jadi, ini akan mengemulasi Linq atas SQL, bukan LINQ atas objek, kan?
Pekerjaan
@ Pekerjaan: ya, itu dirancang untuk SQL. Meskipun saya tidak melihat alasan bahwa itu tidak dapat diperpanjang / diadaptasi untuk objek juga.
mikera
2

Tidak ada fitur asli di java yang meniru linq. Namun, ada beberapa API yang menyediakan fungsionalitas yang sama.

Misalnya, posting blog ini memiliki toples khusus untuk mereplikasi linq.
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html

Dan ini adalah contoh penggunaan API dari pos:

Misalkan kita memiliki objek Hewan yang berisi nama dan ID yang diwakili dengan daftar animals. Jika kita ingin mendapatkan semua nama Hewan yang berisi 'o' dari daftar animals, kita dapat menulis kueri berikut

from(animals).where("getName", contains("o")).all();

Ada dua API lain yang dirujuk dalam posting blog: lambdaJ dan jLinq

Wisnu
sumber
1
Saya takut kehilangan kedua jenis statis memeriksa dan memeriksa keberadaan anggota kelas adalah sedikit curam harga untuk panggilan seperti where("getName", ...).
9000