Linq ile en iyi Java eşdeğeri nedir? [kapalı]


17

Java'da Linq'in işlevselliğini sağlamaya yaklaşan bir kütüphane var mı?


1
Sanırım "LINQ işlevselliği" yerine "LINQ sözdizimi" anlamına geliyorsunuz. Aynı işlevselliği sağlayan birçok kütüphane vardır :-)
mikera

Java eşdeğeri büyük olasılıkla Groovy'dir . Yine de tip güvenliğini kaybetme pahasına
gnat

Yanıtlar:


20

Tam LINQ sorgu sözdizimini elde etmek için, yeni anahtar kelimeleri ve sözdizimi yapısını destekleyen dil spesifikasyonlarını ve derleyicileri güncellemeniz gerekir. Bu, çoğu okuyucunun çok ötesinde.

Java'da Linq benzeri yöntem-zincir sözdizimini C # 'daki gibi görünen ve çalışan bir şekilde almak için Java'nın desteklemediği iki şeye ihtiyacınız vardır; genişletme yöntemleri (bir örneğe örnek yöntemi gibi uygulanabilen statik yöntemler) ve lambda ifadeleri (anonim delegeler). Ancak, biraz ekstra kodlama ayrıntısına girmeye istekli iseniz, bu ikisi mevcut Java yapılarıyla taklit edilebilir. Java hakkında özellikle şaşırtıcı bulduğum bir şey, anonim arayüz uygulamaları oluşturma yeteneğidir; ihtiyacınız olan her yöntem imzası için bir arabirim olması koşuluyla, basit anonim delegelere izin veren tek bir saf işlev içeren bir arabirime uygulanır.

Bu nedenle, bir yöntem zinciri olarak Linq'in IEnumerable (Javaheads için yinelenebilir) tarafının Java'da yaklaşık olması mümkün olmalıdır; temel olarak bir monad'ı kontrol eden akıcı bir arayüz olarak uygularsınız. LinqIterableTekrarlanabilir bir uygulama gibi bir sınıfa ihtiyacınız vardır:

  • Yinelenebilir herhangi bir girişi LinqIterable örneğine dönüştürebilir
  • filtreleme, gruplama, birleştirme, kavşak, sıralama vb. gibi tek liste arayüzlerini kabul eden ve yeni LinqIterable'lar üreten, bu yöntemlerin umarım "tembel" bir şekilde zincirlenmesine izin veren temel liste işleme yöntemleri vardır.
  • LinqIterable cihazını tekrar ToList, ToArray, ToMap, vb. gibi "somut" nesnelere dönüştürme yöntemleri vardır

Yani, muhtemelen aşağıdaki gibi bir ifadeye izin verecek bir "akıcı" kütüphane tanımlayabilirsiniz:

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

Gerçek kütüphanenin oluşturulması, bir İnternet Soru-Cevap yanıtının kapsamının çok ötesinde bir alıştırmadır. Sadece mümkün olduğunu söyledim, kolay değil.

İfade ağaçları roket bilimi değildir, ancak .NET'in bu alanda sahip olduklarını uygulamak önemli bir proje olacaktır; sadece bir ifade ağacı oluşturma yeteneğine değil, yayılan bayt kodları kullanarak bu ağacı anında "derleyebilmeniz" gerekir; Java'nın yansımasının o kadar güçlü olup olmadığını bilmiyorum.


2
Funnily yeterince genişleme yöntemleri ve lambda ifadeleri her ikisi de Java 8'de. Belki de LINQ geliyor?
lxs

4
Eğer uzatma yöntemleri ve lambdas varsa, büyük bir çaba olmadan .NET Linq "Numaralandırılabilir" tarafına sahip. Dediğim gibi, yine de, Linq sorgusu yapan anahtar kelimelere izin vermek için Java özelliklerinde bir değişiklik gerekiyor, ancak dürüst olmak gerekirse, günlük Linq kullanımında, o kadar kolay olmayan çok fazla sorgu bulamadım bir yöntem zinciri olarak ifade edilir ve derleyici Linq sözdizimini yöntem zincirlerine dönüştürür (çoğu sorgu ve zincir arasında 1: 1 dönüştürebilen VS eklentileri mevcuttur). Bir sonraki gerçek basamak taşı ifade ağaçları olacaktır (Queryable Linq).
KeithS

8

Görmek:


1
bu kaynakların her birinin ne olduğuna biraz genişlemeyi düşünebilir misiniz ve bunları neden sorulan soruya cevap olarak öneriyorsunuz? "Yalnızca Bağlantı cevaplar" oldukça Stack Borsası hoş karşılanmaz
tatarcık

Hmm, sanırım bu Q'nun zaten cevaplanmış olduğu bir durum - kopya olarak değiştirilmelidir?
Martijn Verburg

1
@MartijnVerburg - soruları siteler arasında kopya olarak işaretleyemeyiz. Cevapların gerçekten yalnız kalabilmesi gerekir.
ChrisF

Düzenlendi, umarım şimdi biraz daha faydalıdır.
Martijn Verburg

5

Hayır. Linq, Java'nın sadece dozajda sahip olduğu birçok lang özellik gerektirir


4
Java'nın jenerikleri vardır.
Jonas

6
@Jonas: Bu doğru, ancak LINQ'yu destekleyecek kadar güçlü olup olmadıkları başka bir konudur.
DeadMG

2
@DeadMG hala Java'nın jenerikleri var.
Mahmoud Hossam

Jenerik referansı kaldırmak için düzenlendi
Tom Squires

3

Kullanım Scala için sebepler burada izah :

Scala'nın .NET portunu kullanın. Açıkçası LINQ içeren .NET'teki her şeye tam yerel erişim sağlar.

Eğer yapamıyorsanız, functionjava veya lambdaj gibi libs kullanmaya çalışabilirsiniz , ancak LINQ'ya gerçekten yaklaşmayacaksınız.


1
Scala, kütüphanesiz Linq gibi bir şey içermez.
Jonas

1
@Jonas: Öyleyse? Java Linq böyle bir şey içermez ile kütüphaneler.
back2dos

@ back2dos: Evet, bu yüzden bir kütüphane ile cevap vermelisiniz.
Jonas

1
@Jonas: Scala'nın standart kütüphanesi LINQ gibidir. Ya da tam tersi: LINQ sadece C # için bir dizi işlevsel programlama deyimidir. Burada daha fazlası .
back2dos

@ back2dos: Harika bağlantı için teşekkürler, onu dahil etme özgürlüğünü aldım.
Landei


2

Sen kullanabilirsiniz Korma , Clojure yazılan SQL sorguları için DSL.

Sözdizimi oldukça düzgün:

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

İlgili Clojure kitaplıklarını içe aktararak ve yalnızca normal Clojure / Java birlikte çalışmasını kullanarak bunu Java'dan kolayca çağırabilirsiniz.


Yani, bu nesneler üzerinde LINQ değil, SQL üzerinde Linq öykünecek, değil mi?
İş

@ İş: evet, SQL için tasarlanmıştır. Yine de, nesneler için de genişletilemedi / uyarlanamaması için bir neden göremiyorum.
mikera

2

Java'da linq'i taklit eden yerel bir özellik yoktur. Ancak, aynı işlevselliği sağlayan birkaç API vardır.

Örneğin, bu blog yazısında linq çoğaltmak için özel bir kavanoz vardır.
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html

Ve bu, gönderiden API'nin örnek bir kullanımıdır:

Bir liste ile temsil edilen ad ve kimlik içeren bir Animal neslimiz olduğunu varsayalım animals. Listeden 'o' içeren tüm Hayvan adlarını almak istiyorsak animals, aşağıdaki sorguyu yazabiliriz

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

Blog gönderisinde referans verilen iki API daha var: lambdaJ ve jLinq


1
Korkarım, hem statik tip kontrolünü kaybetmek hem de bir sınıf üyesinin varlığını kontrol etmek, biraz çağrı gibi çağrı yapmak için biraz dik bir fiyattır where("getName", ...).
9000
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.