Qual è l'equivalente Java per LINQ? [chiuso]


820

Cos'è l'equivalente Java per LINQ?


4
Quelli sembrano essere LINQ to SQL.
SLaks

8
Dai un'occhiata a questo: github.com/nicholas22/jpropel-light, esempio reale: new String [] {"james", "john", "john", "eddie"} .where (startWith ("j")). ToList () .distinct ();
NT_

1
Java ppl usa ancora più istruzioni e foreach loop che possono essere risolti da Linq ...
om471987

1
Anche per Scala con API LINQ completa: github.com/nicholas22/propelS
Scooterville

4
@craastad Essendo un ragazzo .NET ora bloccato per lo più nel mondo Java, sento il tuo dolore. Dovresti provare Scala - funzioni / chiusure di prima classe, per le comprensioni (non uguali alla sintassi delle query di LINQ, ma utili in molte delle stesse situazioni), un sistema di tipo unificato, inferenza di tipo, alcune soluzioni utili per la cancellazione di tipo generico ... tutto in esecuzione su JVM, interagendo con Java. Inoltre un sacco di altre bontà funzionali come la corrispondenza dei modelli, il tipo di opzione, ecc.
Tim Goodman,

Risposte:


808

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

:-)


9
c'è qualcosa nel piano? integrato nella lingua? C'è un numero JCP? ecc. ecc.
Cheeso

6
È vero, anche se gran parte di ciò che rende LINQ così bello è quanto profondamente sia integrato nel linguaggio e nel compilatore
AgileJon

11
Siamo spiacenti, il "vero" era pensato per 280Z28. Non so se esiste un JCP per questo. LINQ ha reso necessarie diverse modifiche al linguaggio C #, data la velocità con cui il JCP funziona, non tratterei il respiro.
AgileJon

12

23
LINQ è una specifica, non un'implementazione ... Le espressioni Lambda fanno parte di LINQ. Tutti i progetti che provano a trasferire LINQ su Java sono implementazioni per uno scenario concreto (SQL, Oggetti ...) ma non coprono l'obiettivo principale di LINQ: integrare la query di lingua nel codice. A causa di ciò, per ora non esiste alternativa né iniziativa reale che possa essere considerata un'alternativa.
sesispla,

154

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

7
Stringa per il nome della colonna, il che significa che il compilatore e il completamento automatico IDE non aiuteranno contro errori di battitura e il refactoring è difficile. Hai intenzione di cambiarlo?
Ekevoo,

2
Ciao Ekevoo. Penso che sarà meraviglioso e ho provato a farlo qualche volta. Ma in questo momento, con Java 8, Coollection è una lib obsoleta. Forse è utile per i progetti più vecchi ... Cosa ne pensi?
19WAS85

1
@WagnerAndrade L'ultimo commit è di 5-6 anni fa. Suppongo che la funzionalità sia stata ampiamente sostituita da Java 8? Inoltre, bel nome :)
Abdul,

145

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 .


Lambdas non era programmato anche per essere in Java 7? Cos'è successo a quello?
BlueRaja - Danny Pflughoeft l'

7
Oracle ha acquistato Sun (la lingua nella guancia). Java 7 stava impiegando troppo tempo (5 anni), quindi Lambdas ha perso la lista, questo è stato piuttosto deludente per le masse. Detto questo, Oracle sembra prendere la palla e penso che siamo in programma per Java l'8 ottobre del prossimo anno.
Brett Ryan,

1
Si noti che lo stato della Lambda è stato nuovamente aggiornato, che ora copre flussi, iterazione interna, cortocircuito e riferimenti del costruttore. Consiglio a tutti di leggere il nuovo documento.
Brett Ryan,

6
Le espressioni lambda sono una piccola parte di LINQ.
sesispla,

4
@NeWNeO, se ti riferisci al linguaggio di query in C # allora sì, nulla di simile sta arrivando a Java, tuttavia nella mia esperienza la maggior parte degli sviluppatori C # esperti preferisce la sintassi lambda rispetto al linguaggio di query. Tuttavia, se ad esempio ti riferisci a LINQ-to-Entities, scoprirai che lambdas in java consentirà questo e altro. C'è molto di più in arrivo su Java 8 per abilitare questo, come i metodi di difesa .
Brett Ryan,

119

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.


6
Questo è carino, ma è ben lungi dall'essere sul punto di costruire una query ed eseguirla di nuovo sql, xml, collection, ecc.
bytebender

perché dovrei ricevere java.lang.ExceptionInInitializerError quando utilizzo lambdaj select su una classe personalizzata nel mio progetto Android?
topwik,

1
+1 questo è davvero buono per quelli di noi che non si preoccupano di SQL / XML e vogliono solo un accesso più facile alle raccolte.
ashes999,

101

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


github.com/TrigerSoft/jaque trovato in questo modo e consente di creare alberi di espressioni. In combinazione con Java 8 Lambdas, qualsiasi capacità LINQ può essere implementata con lo stesso sforzo di .Net.
Konstantin Triger,

Vedere questa risposta per un confronto: stackoverflow.com/questions/25989449/...
Konstantin Triger

49

LINQ to Objects - JAVA 8 ha aggiunto l'API Stream che aggiunge il supporto per le operazioni in stile funzionale su flussi di valori:

Pacchetto java.util.stream

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/


Non so perché i lettori non abbiano prestato attenzione alla tua risposta, anche se Stream API è la più vicina a LINQ!
Rafid,

3
API Stream è uno scherzo paragonato a LINQ.
Andrei Rînea,

1
Scusa amico, non voglio essere scortese. Stavo cercando un equivalente LINQ dopo aver battuto la testa con API streaming. volevo solo dire che non è un vero equivalente, tutto qui.
Andrei Rînea,

1
@ AndreiRînea Stai cercando funzionalità equivalenti ai provider LINQ (LINQ to XML, LINQ to JSON, LINQ to NHibernate, ecc.)?
Răzvan Flavius ​​Panda,

2
Tutto ciò di cui avevo bisogno era un mezzo per raggruppare e max su una collezione .. Alla fine ci sono riuscito, ma con molto sforzo e troppo codice.
Andrei Rînea,

29

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.


2
Quaere sembra fornire un po 'di quello che offre LINQ, ma la domanda è per un "equivalente"
AgileJon

6
Quindi è qualcosa come LINQ, se non un equivalente diretto? Almeno sembra utile
Brian Agnew,

3
@AgileJon: se intendesse davvero equivalente, non avrebbe chiesto. Avrebbe potuto digitare from x in xs select xe scoprire la risposta (no).
kizzx2,

18

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.


6
Il link "framework simili" è morto. Hai ancora una pagina equivalente?
Lukas Eder,

Quando avremo un libro su QueryDSL? O anche opzioni di allenamento convenienti? Il tuo link di supporto 404s.
Kervin,

16

puoi usare scala, è simile nella sintassi ed è probabilmente più potente di linq.


1
Esp. Scala per "comprensione".
Nico,

10

Come nel 2014, posso finalmente dire che LINQ è finalmente arrivato in Java 8. Quindi non c'è più bisogno di trovare un'alternativa di LINQ.


9

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 .


8

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.


6
Potresti voler menzionare il tuo ruolo nel progetto.
Thorbjørn Ravn Andersen,

8

Implementazione Java LINQ to SQL . Fornisce integrazione linguistica completa e set di funzionalità più ampio rispetto a .NET LINQ.


2
Posso usare JaQue per leggere / scrivere file XML nello stesso modo in cui possiamo fare con LINQ?
Khurram Majeed,

7

Ho provato le librerie guava da google. Ha un FluentIterableche 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.


7

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

5

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.





4

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.


4

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


3

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.


2

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


2

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

1

JaQu è l'equivalente LINQ per Java. Sebbene sia stato sviluppato per il database H2, dovrebbe funzionare per qualsiasi database poiché utilizza JDBC.


1

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.


1
Groovy o jRuby sarebbero anche candidati validi, dal momento che tutti hanno una natura molto più funzionale.
cdeszaq,

1

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


1

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.


1
Scala ha bisogno di un runtime Java per funzionare: non funzionerà necessariamente su un'installazione Linux nuda a seconda dei componenti installati.
Rup

@Rup c'è JRE pienamente compatibile per GNU / Linux e Mono non è un'implementazione .NET pienamente conforme .
Visualizza nome

@Sarge Non era questo il mio punto, ma Mono fa funzionare LINQ abbastanza bene, vero? Inoltre, ora c'è il .Net Core per Linux di Microsoft .
Rup,

(GNU /) Linux non è l'unica piattaforma oltre a Windows, e JRE esiste per un'ampia varietà di piattaforme. Mono non implementa completamente tutto, ad esempio non esiste WPF.
Visualizza nome

0

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.


1
Certo, è stato perseguito, ma non sotto il nome di "Pizza". I generici di Pizza furono uniti in GJ, che divenne poi il compilatore di riferimento Java 1.3 (sebbene i generici fossero nascosti dietro una bandiera fino all'1.5). Nel frattempo ... il resto delle idee, oltre a qualche extra, è diventato Scala.
Kevin Wright,

Grazie per queste informazioni, ovviamente Scala è un buon punto qui. Ma queste abilità non erano integrate nel linguaggio Java. È possibile utilizzare il linguaggio Scala per implementare il simpatico codice di query e utilizzare il binario risultante quindi da Java.
Nico,

Vedi anche ONGL su commons.apache.org/proper/commons-ognl , che è in uso e ancora in manutenzione.
Nico,


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.