Cos'è l'equivalente Java per LINQ?
Cos'è l'equivalente Java per LINQ?
Risposte:
Non c'è niente come LINQ per Java.
...
modificare
Ora con Java 8 ci viene presentato l' API Stream , questo è un tipo di cosa simile quando si tratta di raccolte, ma non è esattamente la stessa di Linq.
Se è un ORM che stai cercando, come Entity Framework, puoi provare Hibernate
:-)
Esiste una soluzione alternativa, Coollection .
Coolection non ha fatto finta di essere il nuovo lambda, tuttavia siamo circondati da vecchi progetti Java legacy in cui questa lib aiuterà. È davvero semplice da utilizzare ed estendere, coprendo solo le azioni di iterazione più utilizzate sulle raccolte, in questo modo:
from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();
Le Lambdas sono ora disponibili in Java 8 sotto forma di JSR-335 - Lambda Expressions per il linguaggio di programmazione JavaTM
AGGIORNAMENTO : è stato ora rilasciato JDK8 che contiene il progetto lambda. Vale la pena prendere una copia di Java 8 in Action attualmente ancora MEAP.
Leggi gli articoli di Brian Goetz relativi a lambda per una discreta comprensione di come i lambda sono implementati all'interno di JDK8, acquisendo al contempo una comprensione di flussi, iterazione interna, cortocircuito e riferimenti dei costruttori. Controlla anche i precedenti di JSR per ottenere ulteriori esempi .
Ho scritto un blog su alcuni dei vantaggi dell'utilizzo di lambda in JDK8 chiamato The Power of the Arrow , anche NetBeans 8 ha un ottimo supporto per convertire i costrutti in JDK8 che ho anche scritto sul blog sulla migrazione a JDK 8 con NetBeans .
Puoi selezionare gli elementi in una raccolta (e molto altro) in un modo più leggibile usando la libreria lambdaj
https://code.google.com/archive/p/lambdaj/
Ha alcuni vantaggi rispetto alla libreria Quaere perché non usa alcuna stringa magica, è completamente sicuro e a mio avviso offre un DSL più leggibile.
Non troverai un equivalente di LINQ se non usi javacc per creare il tuo equivalente.
Fino a quel giorno in cui qualcuno trova un modo fattibile per farlo, ci sono alcune buone alternative, come
LINQ to Objects - JAVA 8 ha aggiunto l'API Stream che aggiunge il supporto per le operazioni in stile funzionale su flussi di valori:
Spiegazione di Java 8: applicazione di Lambdas alle raccolte Java
LINQ to SQL / NHibernate / ecc. (query del database) - Un'opzione sarebbe quella di utilizzare JINQ che utilizza anche le nuove funzionalità di JAVA 8 ed è stato rilasciato il 26 febbraio 2014 su Github: https://github.com/my2iu/Jinq
Jinq offre agli sviluppatori un modo semplice e naturale per scrivere query su database in Java. È possibile trattare i dati del database come normali oggetti Java memorizzati nelle raccolte. È possibile scorrere su di essi e filtrarli utilizzando i normali comandi Java e tutto il codice verrà automaticamente tradotto in query di database ottimizzate. Infine, sono disponibili query in stile LINQ per Java!
Sito del progetto JINQ: http://www.jinq.org/
C'è un progetto chiamato quaere .
È un framework Java che aggiunge la possibilità di interrogare le raccolte.
Nota: secondo l'autore, il progetto non è più mantenuto.
from x in xs select x
e scoprire la risposta (no).
Esistono molti equivalenti LINQ per Java, vedere qui per un confronto.
Per un framework tipafe Quaere / LINQ style, considera l'utilizzo di Querydsl . Querydsl supporta le raccolte JPA / Hibernate, JDO, SQL e Java.
Sono il manutentore di Querydsl, quindi questa risposta è parziale.
Come nel 2014, posso finalmente dire che LINQ è finalmente arrivato in Java 8. Quindi non c'è più bisogno di trovare un'alternativa di LINQ.
Ora che Java 8 supporta lambdas, è possibile creare API Java che assomigliano molto a LINQ.
Jinq è una di queste nuove librerie in stile LINQ per Java.
Sono lo sviluppatore di questa libreria. Si basa su cinque anni di ricerca sull'utilizzo dell'analisi bytecode per tradurre query da Java a database. Simile al modo in cui D-LINQ di C # è un livello di query che si trova sopra Entity Framework, Jinq è in grado di agire come un livello di query posizionato sopra JPA o jOOQ. Ha il supporto per aggregazione, gruppi e sottoquery. Anche Erik Meijer (il creatore di LINQ) ha riconosciuto Jinq .
Vedi SBQL4J . È un linguaggio di query sicuro sicuro per i tipi integrato con Java. Permette di scrivere query complesse e moltiplicate. Ci sono molti operatori, i metodi Java possono essere invocati all'interno delle query come costruttori. Le query vengono tradotte in puro codice Java (non c'è riflesso in fase di esecuzione), quindi l'esecuzione è molto veloce.
EDIT: Bene, finora SBQL4J è l'UNICA estensione al linguaggio Java che offre funzionalità di query simili a LINQ. Esistono alcuni progetti interessanti come Quaere e JaQue ma sono solo API, non estensioni di sintassi / semantiche con una forte sicurezza dei tipi in fase di compilazione.
Implementazione Java LINQ to SQL . Fornisce integrazione linguistica completa e set di funzionalità più ampio rispetto a .NET LINQ.
Ho provato le librerie guava da google. Ha un FluentIterable
che penso sia vicino a LINQ. Vedi anche FunctionalExplained .
List<String> parts = new ArrayList<String>(); // add parts to the collection.
FluentIterable<Integer> partsStartingA =
FluentIterable.from(parts).filter(new Predicate<String>() {
@Override
public boolean apply(final String input) {
return input.startsWith("a");
}
}).transform(new Function<String, Integer>() {
@Override
public Integer apply(final String input) {
return input.length();
}
});
Sembra essere una vasta libreria per Java. Certamente non è succinto come LINQ ma sembra interessante.
https://code.google.com/p/joquery/
Supporta diverse possibilità,
Raccolta data,
Collection<Dto> testList = new ArrayList<>();
di tipo,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Filtro
Java 7
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property("id").eq().value(1);
Collection<Dto> filtered = query.list();
Java 8
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property(Dto::getId)
.eq().value(1);
Collection<Dto> filtered = query.list();
Anche,
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.property(Dto::getId).between().value(1).value(2)
.and()
.property(Dto::grtText).in().value(new string[]{"a","b"});
Ordinamento (disponibile anche per Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Raggruppamento (disponibile anche per Java 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Joins (disponibile anche per Java 7)
Dato,
class LeftDto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
class RightDto
{
private int id;
private int leftId;
private String text;
public int getId()
{
return id;
}
public int getLeftId()
{
return leftId;
}
public int getText()
{
return text;
}
}
class JoinedDto
{
private int leftId;
private int rightId;
private String text;
public JoinedDto(int leftId,int rightId,String text)
{
this.leftId = leftId;
this.rightId = rightId;
this.text = text;
}
public int getLeftId()
{
return leftId;
}
public int getRightId()
{
return rightId;
}
public int getText()
{
return text;
}
}
Collection<LeftDto> leftList = new ArrayList<>();
Collection<RightDto> rightList = new ArrayList<>();
Può essere unito come,
Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
.<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
.on(LeftFyo::getId, RightDto::getLeftId)
.transformDirect(selection -> new JoinedDto(selection.getLeft().getText()
, selection.getLeft().getId()
, selection.getRight().getId())
)
.list();
espressioni
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
Puoi provare la mia libreria CollectionsQuery . Permette di eseguire LINQ come query su raccolte di oggetti. Devi passare il predicato, proprio come in LINQ. Se stai usando java6 / 7 di quanto devi usare la vecchia sintassi con le interfacce:
List<String> names = Queryable.from(people)
.filter(new Predicate<Person>() {
public boolean filter(Person p) {
return p.age>20;
}
})
.map (new Converter<Person,String>() {
public Integer convert(Person p) {
return p.name;
}
})
.toList();
Puoi anche usarlo in Java8, o nella vecchia java con RetroLambda e il suo plugin gradle , quindi avrai una nuova sintassi di fantasia:
List<String> names = Queryable.from(people)
.filter(p->p.age>20)
.map (p->p.name)
.toList();
Se hai bisogno di eseguire query DB, allora puoi guardare su JINQ, come menzionato sopra, ma non può essere trasferito da RetroLambda, per usare lambda serializzati.
Solo per aggiungere un'altra alternativa: Java 6 ha una soluzione per query di database di tipo sicuro usando il pacchetto javax.persistence.criteria .
Anche se devo dire che questo non è davvero LINQ, perché con LINQ puoi interrogare qualsiasi IEnumerable.
C'è una libreria molto buona che puoi usare per questo.
Si trova qui: https://github.com/nicholas22/jpropel-light
Lambdas non sarà disponibile fino a Java 8, quindi usarlo è un po 'diverso e non sembra naturale.
Sembra che il Linq di cui tutti parlino qui sia solo LinqToObjects. Il che credo offre solo funzionalità che possono essere già realizzate oggi in Java, ma con una sintassi davvero brutta.
Quello che vedo come il vero potere di Linq in .Net è che le espressioni lambda possono essere utilizzate in un contesto che richiede un delegato o un'espressione e verranno quindi compilate nella forma appropriata. Questo è ciò che consente a cose come LinqToSql (o qualsiasi altra cosa diversa da LinqToObjects) di funzionare e consente loro di avere una sintassi identica a LinqToObjects.
Sembra che tutti i progetti di cui sopra offrano solo le funzionalità di LinqToObjects. Il che mi fa pensare che la funzionalità di tipo LinqToSql non sia all'orizzonte per Java.
Per le raccolte funzionali di base, Java 8 lo ha incorporato, la maggior parte dei principali linguaggi JVM non Java lo hanno incorporato (Scala, Clojure, ecc.), E puoi ottenere aggiunte su librerie per le versioni precedenti di Java.
Per l'accesso integrato in una lingua completa a un database SQL, Scala (funziona su JVM) ha Slick
Per LINQ (LINQ to Objects), Java 8 avrà qualcosa di equivalente, vedi Progetto Lambda .
Ha estensioni LINQ to Objects di Enumerable come roba . Ma per cose LINQ più complicate come Expression ed ExpressionTree (sono necessarie per LINQ to SQL e altri provider LINQ se vogliono fornire qualcosa di ottimizzato e reale), non esiste ancora alcun equivalente ma forse lo vedremo in futuro :)
Ma non credo che ci saranno in futuro domande come dichiarazioni dichiarative su Java.
Non esiste tale funzionalità in Java. Usando l'altra API otterrai questa funzione. Supponiamo di avere un oggetto animale contenente nome e ID. Abbiamo un oggetto elenco con oggetti animali. Ora, se vogliamo ottenere tutto il nome animale che contiene 'o' dall'oggetto elenco. possiamo scrivere la seguente query
from(animals).where("getName", contains("o")).all();
L'istruzione Above Query elenca gli animali che contengono l'alfabeto "o" nel loro nome. Maggiori informazioni si prega di consultare il seguente blog. http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
Dai un'occhiata a tiny-q . (Nota che al momento non puoi scaricarlo.)
Ecco un esempio adattato il link sopra:
Per prima cosa abbiamo bisogno di una raccolta di alcuni dati, diciamo una serie di stringhe
String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };
Ora vogliamo selezionare solo le stringhe che iniziano con "b":
Query<String> stringsStartingWithB = new Query<String>(strings).where(
new Query.Func<String, Boolean>(){
public Boolean run(String in) {
return in.startsWith("b");
}
}
);
Nessun dato reale trasferito viene copiato o qualcosa del genere, verrà elaborato non appena si inizia a iterare:
for(String string : stringsStartingWithB ) {
System.out.println(string);
}
JaQu è l'equivalente LINQ per Java. Sebbene sia stato sviluppato per il database H2, dovrebbe funzionare per qualsiasi database poiché utilizza JDBC.
Forse non è la risposta che speri, ma se alcune parti del tuo codice necessitano di un intenso lavoro sulle raccolte (ricerca, ordinamento, filtro, trasformazioni, analisi) potresti prendere in considerazione di scrivere alcune classi in Clojure o Scala .
A causa della loro natura funzionale, lavorare con le collezioni è ciò che fanno meglio. Non ho molta esperienza con Scala, ma con Clojure probabilmente troverai un Linq più potente a portata di mano e, una volta compilate, le classi che produresti si integrerebbero perfettamente con il resto della base di codice.
Un utente anonimo ne ha menzionato un altro, Diting :
Diting è una libreria di classi che offre funzionalità di query sulle raccolte tramite metodi concatenabili e interfaccia anonima come Linq in .NET. A differenza della maggior parte delle altre librerie di raccolta che utilizzano metodi statici richiedono iterare l'intera raccolta, Diting fornisce una classe Enumerabile di base che contiene metodi concatenabili differiti per implementare query su raccolta o array.
Metodi supportati: any, cast, contact, contiene, count, distinti, elementAt, tranne, first, firstOrDefault, groupBy, interset, join, last, lastOrDefault, ofType, orderBy, orderByDescending, reverse, select, selectMany, single, singleOrDefault, skip , skipWhile, take, takeWhile, to Array, to ArrayList, union, where
Scala.Ora l'ho letto, e l'ho trovato come linq, ma più semplice e illeggibile. ma scala può funzionare su Linux, sì? csharp ha bisogno di mono.
C'era il linguaggio di programmazione Pizza (un'estensione Java) e dovresti dargli un'occhiata. - Utilizza il concetto di "interfacce fluenti" per eseguire query sui dati in modo dichiarativo e che è in linea di principio identico alle espressioni di query LINQ w / o (http://en.wikipedia.org/wiki/Pizza_programming_language). Ma purtroppo non è stato perseguito, ma sarebbe stato un modo per ottenere qualcosa di simile a LINQ in Java.
Non esiste un equivalente a LINQ per Java. Ma c'è qualche API esterna che sembra LINQ come https://github.com/nicholas22/jpropel-light , https://code.google.com/p/jaque/
puoi provare questa libreria: https://code.google.com/p/qood/
Ecco alcuni motivi per usarlo: