Qual è il miglior equivalente Java a Linq? [chiuso]


17

Esistono librerie in Java che si avvicinano per fornire la funzionalità di Linq?


1
Presumo che tu intenda "la sintassi di LINQ" anziché "la funzionalità di LINQ". Esistono molte librerie che offrono le stesse funzionalità :-)
mikera,

L'equivalente Java è molto probabilmente Groovy . A scapito di perdere la sicurezza del tipo però
moscerino il

Risposte:


20

Per ottenere la sintassi completa delle query LINQ, è necessario un aggiornamento delle specifiche della lingua e dei compilatori che supportano le nuove parole chiave e la struttura della sintassi. Questo è molto al di là della maggior parte dei lettori qui.

Per ottenere una sintassi della catena di metodi simile a Linq in Java che assomigli e funzioni come in C #, hai bisogno di due cose che Java non supporta; metodi di estensione (metodi statici che possono essere applicati a un'istanza come se fosse un metodo di istanza) ed espressioni lambda (delegati anonimi). Tuttavia, questi due possono essere falsificati con costrutti Java esistenti, se si è disposti a incorrere in un po 'più di verbosità di codifica. Una cosa che trovo particolarmente sorprendente di Java è la capacità di creare implementazioni di interfaccia anonime; applicato a un'interfaccia con un'unica funzione pura, che consente sostanzialmente semplici delegati anonimi, purché tu abbia un'interfaccia per ogni firma del metodo di cui avrai bisogno.

Quindi, il lato IEnumerable (Iterable for the Javaheads) di Linq, come una catena di metodi, dovrebbe essere possibile approssimare in Java; lo implementeresti fondamentalmente come un'interfaccia fluida che controlla una monade. Avresti bisogno di una classe come una LinqIterable, implementando Iterable, che:

  • può convertire qualsiasi input Iterable in un'istanza LinqIterable
  • dispone di metodi per l'elaborazione di elenchi di base, come filtraggio, raggruppamento, concatenazione, intersezione, ordinamento, ecc. che accettano interfacce a funzione singola e producono nuovi LinqIterables, consentendo il concatenamento di questi metodi, si spera in modo "pigro".
  • ha metodi per trasformare LinqIterable in oggetti "concreti" come ToList, ToArray, ToMap, ecc.

Quindi, potresti probabilmente definire una libreria "fluente" che consentirebbe una dichiarazione come:

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

La creazione della biblioteca reale è un esercizio che va ben oltre lo scopo di una risposta su una domanda e risposta su Internet. Ho appena detto che era possibile, non facile.

Gli alberi delle espressioni non sono scienza missilistica, ma sarebbe un progetto significativo per implementare ciò che .NET ha in quest'area; non solo hai bisogno della capacità di costruire un albero delle espressioni, ma devi anche essere in grado di "compilare" questo albero al volo usando i bytecode emessi; Non so se il riflesso di Java sia così potente.


2
Stranamente metodi di estensione ed espressioni lambda sono entrambi in Java 8. Forse LINQ è in arrivo?
lx

4
Bene, se hai metodi di estensione e lambda, hai il lato "Enumerabile" di Linq di .NET senza un grande sforzo. Tuttavia, come ho detto, richiederà ancora una modifica alle specifiche Java per consentire le parole chiave che eseguono una query Linq, ma onestamente nell'uso quotidiano di Linq non ho trovato troppe query che non sono altrettanto facili espresso come una catena di metodi e il compilatore converte praticamente la sintassi di Linq in catene di metodi (esistono plugin VS che possono convertire 1: 1 tra la maggior parte delle query e delle catene). Il prossimo vero trampolino di lancio saranno gli alberi delle espressioni (Queryable Linq).
KeithS

8

Vedere:


1
ti dispiacerebbe ampliare un po 'quello che ognuna di queste risorse ha e perché le consigli a rispondere alla domanda posta? Le "risposte solo link" non sono del tutto benvenute allo Stack Stack
moscerino del

Hmm, immagino sia un caso che a questa Q fosse già stata data una risposta - dovrebbe essere modificato come duplicato?
Martijn Verburg,

1
@MartijnVerburg - non possiamo contrassegnare le domande come duplicati su tutti i siti. Le risposte devono davvero essere in grado di stare da sole.
ChrisF

A cura, spero sia un po 'più utile ora.
Martijn Verburg,

5

No. Linq richiede molte funzionalità di lingua che Java ha appena dosent


4
Java ha generici.
Jonas,

6
@Jonas: È vero, ma se sono effettivamente abbastanza forti da supportare LINQ è un'altra cosa.
DeadMG,

2
@DeadMG ancora, Java ha generici.
Mahmoud Hossam,

A cura di rimuovere il riferimento ai generici
Tom Squires,

3

Usa Scala , per i motivi spiegati qui :

usa la porta .NET di Scala. Ti dà pieno accesso nativo a tutto in .NET, che ovviamente include LINQ.

Se non ci riesci, puoi provare a usare lib come functionjava o lambdaj , ma non ti avvicinerai molto a LINQ.


1
Scala non include nulla di simile a Linq senza librerie.
Jonas,

1
@Jonas: Quindi? Java non include nulla come Linq con le librerie.
back2dos,

@ back2dos: Sì, ecco perché devi rispondere con una biblioteca.
Jonas,

1
@Jonas: la libreria standard di Scala è come LINQ. O viceversa: LINQ è solo un insieme di idiomi di programmazione funzionale per C #. Maggiori informazioni qui .
back2dos,

@ back2dos: grazie per l'ottimo link, ho preso la libertà di includerlo.
Landei,

2

Aggiungerei guava all'elenco delle librerie che potrebbero aiutarti a realizzare alcune delle cose che LINQ fa.

Ma come altri hanno sottolineato, non esiste un equivalente in Java puro.


ti dispiacerebbe spiegare di più su ciò che fa e perché lo consigli come rispondere alla domanda posta? Le "risposte solo link" non sono del tutto benvenute allo Stack Stack
moscerino del

2

È possibile utilizzare Korma , una query DSL per SQL scritta in Clojure.

La sintassi è piuttosto ordinata:

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

Puoi chiamarlo abbastanza facilmente da Java importando le relative librerie Clojure e semplicemente usando la normale interoperabilità Clojure / Java.


Quindi, questo emulerà Linq su SQL, non LINQ su oggetti, giusto?
Lavoro

@Job: sì, è progettato per SQL. Anche se non vedo alcun motivo per cui non possa essere esteso / adattato anche per gli oggetti.
Mikera,

2

Non esiste una funzione nativa in Java che imita Linq. Tuttavia, ci sono diverse API che offrono la stessa funzionalità.

Ad esempio, questo post di blog ha un barattolo personalizzato per replicare linq.
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html

E questo è un esempio di utilizzo dell'API dal post:

Supponiamo di avere un oggetto Animale contenente nome e ID che è rappresentato con un elenco di animals. Se vogliamo ottenere tutti i nomi di animali che contengono 'o' dall'elenco animals, possiamo scrivere la seguente query

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

Ci sono altre due API citate nel post del blog: lambdaJ e jLinq


1
Temo che perdere sia il controllo statico del tipo sia il controllo dell'esistenza stessa di un membro della classe sia un po 'caro per richiedere una chiamata del genere where("getName", ...).
9000
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.