Qual é o equivalente em Java para LINQ? [fechadas]

820

O que é equivalente em Java para LINQ?

Ahmed Atia
fonte
4
Aqueles parecem ser LINQ to SQL.
SLaks
8
Verifique este: github.com/nicholas22/jpropel-light, exemplo real: new String [] {"james", "john", "john", "eddie"} .where (beginWith ("j")). ToList () .distinct ();
NT_8 /
1
Ppl Java ainda usam várias instruções e foreach loops que podem ser resolvidos por Linq ...
om471987
1
Também para Scala com API LINQ completa: github.com/nicholas22/propelS
Scooterville
4
@craastad Como um cara do .NET agora preso principalmente no mundo Java, sinto sua dor. Você deve experimentar o Scala - funções / fechamentos de primeira classe, para compreensão (não a mesma sintaxe de consulta do LINQ, mas útil em muitas das mesmas situações), um sistema unificado de tipos, inferência de tipos, algumas soluções práticas para eliminação de tipos genéricos ... tudo rodando na JVM, interoperando com Java. Além de um monte de outras bondade funcional como correspondência de padrões, tipo Option, etc.
Tim Goodman

Respostas:

808

Não há nada como LINQ for Java.

...

Editar

Agora, com o Java 8, somos apresentados à API Stream , esse é um tipo de coisa semelhante ao lidar com coleções, mas não é exatamente o mesmo que Linq.

Se você procura um ORM, como o Entity Framework, pode tentar o Hibernate

:-)

AgileJon
fonte
9
existe algo no plano? integrado ao idioma? Existe um número JCP? etc etc
Cheeso
6
Muito verdadeiro, embora uma grande parte do que faz LINQ sooo nice é o quão profundamente ele é integrado a linguagem e compilador
AgileJon
11
Desculpe, o 'true' foi criado para o 280Z28. Não sei se existe um JCP para isso. O LINQ exigiu várias alterações na linguagem C #, dada a velocidade em que o JCP trabalha, eu não prendia a respiração.
AgileJon
12
Isso não está correto. Veja: stackoverflow.com/questions/10879761/…
Scooterville
23
O LINQ é uma especificação, não uma implementação ... As expressões lambda fazem parte do LINQ. Todos os projetos que tentam portar o LINQ para Java são implementações para um cenário concreto (SQL, Objetos ...), mas não representam o objetivo principal do LINQ: Integrar a consulta de idioma no código. Por esse motivo, não há alternativa real nem iniciativa, por enquanto, que possa ser considerada uma alternativa.
precisa saber é o seguinte
154

Existe uma solução alternativa, Coollection .

O Coolection não pretende ser o novo lambda, no entanto, estamos rodeados por projetos Java antigos e antigos, nos quais essa biblioteca ajudará. É realmente simples de usar e estender, cobrindo apenas as ações de iteração mais usadas em coleções, assim:

from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();
19WAS85
fonte
7
A string para o nome da coluna, o que significa que o compilador e o preenchimento automático do IDE não ajudarão contra erros de digitação e a refatoração é difícil. Algum plano para mudar isso?
Ekevoo
2
Olá Ekevoo. Eu acho que será fantástico e tentei fazer isso algum dia. Mas, neste momento, com o Java 8, a Coollection é uma lib obsoleta. Talvez seja útil para projetos mais antigos ... O que você acha?
19WAS85
1
@WagnerAndrade O último commit é de 5-6 anos atrás. Estou assumindo que a funcionalidade foi amplamente substituída pelo Java 8? Além disso, muito legal nome :)
Abdul
145

Agora, as lambdas estão disponíveis no Java 8 na forma de JSR-335 - Expressões lambda para a linguagem de programação JavaTM

ATUALIZAÇÃO : O JDK8 foi lançado agora que contém o projeto lambda. Vale a pena pegar uma cópia do Java 8 in Action atualmente ainda MEAP.

Leia os artigos de Brian Goetz relacionados aos lambdas para um entendimento decente de como as lambdas são implementadas no JDK8 e, ao mesmo tempo, obtenha um entendimento de fluxos, iteração interna, curto-circuito e referências de construtores. Verifique também as JSRs acima para obter mais exemplos .

Eu escrevi um blog sobre algumas das vantagens de usar lambdas no JDK8, chamado The Power of the Arrow , também o NetBeans 8 tem um ótimo suporte para converter construções em JDK8, que também escrevi sobre a migração para o JDK 8 com o NetBeans .

Brett Ryan
fonte
Os lambdas também não estavam programados para estar no Java 7? O que aconteceu com aquilo?
BlueRaja - Danny Pflughoeft 11/11
7
A Oracle comprou a Sun (língua na bochecha). O Java 7 estava demorando muito (5 anos), então as lambdas perderam a lista curta, o que foi bastante decepcionante para as massas. Dito isto, a Oracle parece estar pegando a bola e acho que estamos programados para Java em 8 de outubro do próximo ano.
Brett Ryan
1
Observe que o estado do Lambda foi atualizado mais uma vez, que agora abrange referências de fluxos, iteração interna, curto-circuito e construtor. Aconselho a todos que leiam o novo documento.
Brett Ryan #
6
Expressões lambda são uma pequena parte do LINQ.
precisa saber é o seguinte
4
@NeWNeO, se você está se referindo à linguagem de consulta em C #, então sim, nada disso está chegando ao Java, no entanto, na minha experiência, os desenvolvedores mais experientes de C # preferem a sintaxe lambda sobre a linguagem de consulta. No entanto, se você estiver se referindo a LINQ-to-Entities, por exemplo, verá que lambdas em java ativará isso e muito mais. Há muito mais disponível no Java 8 para habilitar isso, como métodos de defesa .
Brett Ryan,
119

Você pode selecionar os itens em uma coleção (e muito mais) de uma maneira mais legível usando a biblioteca lambdaj

https://code.google.com/archive/p/lambdaj/

Ele tem algumas vantagens sobre a biblioteca Quaere porque não usa nenhuma string mágica, é completamente seguro para o tipo e, na minha opinião, oferece uma DSL mais legível.

Mario Fusco
fonte
6
Isso é bom, mas é muito longe de estar prestes a construir uma consulta e executá-lo novamente sql, xml, cobrança, etc
bytebender
por que eu poderia estar recebendo java.lang.ExceptionInInitializerError ao usar lambdaj select em uma classe personalizada no meu projeto android?
Topwik 20/08/12
1
Marcar com +1 é realmente bom para aqueles que não se importam com SQL / XML e querem apenas um acesso mais fácil às coleções.
Ashes999
101

Você não encontrará um equivalente ao LINQ, a menos que use o javacc para criar seu próprio equivalente.

Até aquele dia em que alguém encontra uma maneira viável de fazer isso, existem algumas boas alternativas, como

Lukas Eder
fonte
O github.com/TrigerSoft/jaque foi encontrado dessa maneira e vamos criar Árvores de Expressão. Combinado com o Java 8 Lambdas, qualquer capacidade LINQ pode ser implementada com o mesmo esforço que em .Net.
9788 Konstantin Triger #
Veja esta resposta para uma comparação: stackoverflow.com/questions/25989449/…
Konstantin Triger
49

LINQ to Objects - O JAVA 8 adicionou a API Stream, que adiciona suporte para operações de estilo funcional em fluxos de valores:

Pacote java.util.stream

Java 8 Explicado: Aplicando Lambdas a Coleções Java

LINQ para SQL / NHibernate / etc. (consulta ao banco de dados) - Uma opção seria usar o JINQ, que também usa os novos recursos do JAVA 8 e foi lançado em 26 de fevereiro de 2014 no Github: https://github.com/my2iu/Jinq

O Jinq fornece aos desenvolvedores uma maneira fácil e natural de escrever consultas de banco de dados em Java. Você pode tratar dados do banco de dados como objetos Java normais armazenados em coleções. Você pode iterá-los e filtrá-los usando comandos Java normais, e todo o seu código será convertido automaticamente em consultas otimizadas ao banco de dados. Finalmente, as consultas no estilo LINQ estão disponíveis para Java!

Site do projeto JINQ: http://www.jinq.org/

Răzvan Flavius ​​Panda
fonte
Não sei por que os leitores não prestaram atenção à sua resposta, embora a API do Stream seja a mais próxima do LINQ!
Rafid
3
A API do Streams é uma piada de mau gosto em comparação com o LINQ.
Andrei Rînea
1
Desculpe cara, não quero ser rude. Eu estava procurando por um equivalente em LINQ depois de bater na cabeça com a API de fluxos. eu só queria dizer que não é um equivalente real, só isso.
Andrei Rînea 7/08
1
@ AndreiRînea Você está procurando a funcionalidade equivalente de provedores LINQ (LINQ to XML, LINQ to JSON, LINQ to NHibernate, etc.)?
Răzvan Flavius ​​Panda
2
Tudo o que eu precisava era de um meio para agrupar e maximizar uma coleção .. Acabei conseguindo, mas com muito esforço e muito código.
Andrei Rînea 8/08/17
29

Existe um projeto chamado quaere .

É uma estrutura Java que adiciona a capacidade de consultar coleções.

Nota: Segundo o autor, o projeto não é mais mantido.

Sadegh
fonte
2
Quaere parece que fornece um pouco do que LINQ fornece, mas a questão é para um 'equivalente'
AgileJon
6
Então é algo como LINQ, se não um equivalente direto? Que pelo menos soa útil
Brian Agnew
3
@AgileJon: Se ele realmente quis dizer equivalente, ele não teria perguntado. Ele poderia ter digitado from x in xs select xe descoberto a resposta (não).
kizzx2
18

Existem muitos equivalentes LINQ para Java, veja aqui para uma comparação.

Para uma estrutura de estilo Quaere / LINQ tipesafe, considere usar Querydsl . O Querydsl suporta coleções JPA / Hibernate, JDO, SQL e Java.

Eu sou o mantenedor do Querydsl, então essa resposta é tendenciosa.

Timo Westkämper
fonte
6
O link "estruturas semelhantes" está morto. Você ainda tem uma página equivalente?
Lukas Eder
Quando receberemos um livro QueryDSL? Ou mesmo opções de treinamento acessíveis? Seu link de suporte 404s.
kervin
16

você pode usar scala, é semelhante em sintaxe e é provavelmente mais poderoso que o linq.

Erion
fonte
1
Esp. Scala "pela compreensão".
Nico
10

Como em 2014, posso finalmente dizer que o LINQ finalmente está lá no java 8. Portanto, não há mais necessidade de encontrar uma alternativa ao LINQ.

Abhinab Kanrar
fonte
9

Agora que o Java 8 suporta lambdas, é possível criar APIs Java que se assemelham ao LINQ.

Jinq é uma dessas novas bibliotecas no estilo LINQ para Java.

Eu sou o desenvolvedor desta biblioteca. Ele se baseia em cinco anos de pesquisa sobre o uso da análise de bytecode para converter Java em consultas ao banco de dados. Semelhante ao modo como o D-LINQ do C # é uma camada de consulta que fica no topo do Entity Framework, o Jinq é capaz de atuar como uma camada de consulta no JPA ou no jOOQ. Possui suporte para agregação, grupos e subconsultas. Até Erik Meijer (o criador do LINQ) reconheceu Jinq .

Ming-Yee Iu
fonte
8

Veja SBQL4J . É uma linguagem de consulta segura e segura para tipos, integrada ao Java. Permite escrever consultas complicadas e multiplicadas. Existem muitos operadores, métodos Java podem ser chamados dentro de consultas, assim como construtores. As consultas são convertidas em código Java puro (não há reflexão no tempo de execução), portanto, a execução é muito rápida.

EDIT: Bem, até agora o SBQL4J é a única extensão da linguagem Java que fornece recursos de consulta semelhantes ao LINQ. Existem projetos interessantes como Quaere e JaQue, mas eles são apenas APIs, não extensões de sintaxe / semântica com forte segurança de tipo em tempo de compilação.

Emil Wcisło
fonte
6
Você pode mencionar seu papel no projeto.
Thorbjørn Ravn Andersen
8

Implementação de Java LINQ to SQL . Fornece integração completa de idiomas e maior conjunto de recursos em comparação com o .NET LINQ.

Konstantin Triger
fonte
2
Posso usar o JaQue para ler / gravar arquivos XML da mesma maneira que podemos fazer com o LINQ?
Khurram Majeed 15/02
7

Eu tentei bibliotecas de goiaba do google. Ele tem um FluentIterableque eu acho que é próximo ao LINQ. Consulte também 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();
        }
    });

Parece ser uma extensa biblioteca para Java. Certamente não é tão sucinto quanto o LINQ, mas parece interessante.

Madhan Ganesh
fonte
7

https://code.google.com/p/joquery/

Suporta diferentes possibilidades,

Dada a coleção,

Collection<Dto> testList = new ArrayList<>();

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

Além disso,

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

Classificação (também disponível para o Java 7)

Filter<Dto> query = CQ.<Dto>filter(testList)
        .orderBy()
        .property(Dto::getId)
        .property(Dto::getName)
    Collection<Dto> sorted = query.list();

Agrupamento (também disponível para o Java 7)

GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
        .group()
        .groupBy(Dto::getId)
    Collection<Grouping<Integer,Dto>> grouped = query.list();

Junções (também disponíveis para o Java 7)

Dado,

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

Pode ser juntado como,

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

Expressões

Filter<Dto> query = CQ.<Dto>filter()
    .from(testList)
    .where()
    .exec(s -> s.getId() + 1).eq().value(2);
Pelicano voador baixo
fonte
5

Você pode experimentar minha biblioteca CollectionsQuery . Permite executar LINQ como consultas sobre coleções de objetos. Você precisa passar o predicado, assim como no LINQ. Se você estiver usando o java6 / 7, precisará usar a sintaxe antiga do Interfaces:

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

Você também pode usá-lo no Java8, ou no java antigo com RetroLambda e seu plug-in gradle , para ter uma nova sintaxe sofisticada:

List<String> names = Queryable.from(people)
                                    .filter(p->p.age>20)
                                    .map   (p->p.name)
                                    .toList();

Se você precisar executar consultas ao banco de dados, poderá procurar no JINQ, como mencionado acima, mas não pode ser portado pelo RetroLambda, doe para usar lambdas serializadas.

Bogdan Mart
fonte
4

Apenas para adicionar outra alternativa: o Java 6 tem uma solução para consultas de banco de dados com segurança de tipo usando o pacote javax.persistence.criteria .

Embora eu deva dizer que esse não é realmente o LINQ, porque com o LINQ você pode consultar qualquer IEnumerable.

metador
fonte
Sim, é uma API JPA. Longe do LINQ, mas melhor que nada. E pode-se dizer que é baseado livremente na API Hibernate Criteria. Veja: docs.jboss.org/hibernate/core/3.6/reference/en-US/html/…
Hendy Irawan
4

Há uma biblioteca muito boa que você pode usar para isso.

Localizado aqui: https://github.com/nicholas22/jpropel-light

Porém, o Lambdas não estará disponível até o Java 8, portanto, usá-lo é um pouco diferente e não parece tão natural.

Moox
fonte
4

Parece que o Linq que todo mundo está falando aqui é apenas LinqToObjects. Acredito que apenas oferece funcionalidades que já podem ser realizadas hoje em Java, mas com sintaxe realmente feia.

O que vejo como o verdadeiro poder do Linq no .Net é que as expressões lambda podem ser usadas em um contexto que exija um Delegado ou uma Expressão e serão compiladas no formato apropriado. É isso que permite que coisas como o LinqToSql (ou qualquer outra coisa que não seja o LinqToObjects) funcionem e permite que eles tenham uma sintaxe idêntica ao LinqToObjects.

Parece que todos os projetos mencionados acima oferecem apenas os recursos do LinqToObjects. O que me faz pensar que a funcionalidade do tipo LinqToSql não está no horizonte para Java.

MarkPflug
fonte
4

Para coleções funcionais básicas, o Java 8 foi incorporado, a maioria das principais linguagens JVM não Java (Scala, Clojure etc.), e você pode adicionar bibliotecas para versões anteriores do Java.

Para acesso integrado ao idioma completo de um banco de dados SQL, o Scala (executado na JVM) possui o Slick

argila
fonte
3

Para LINQ (LINQ to Objects), o Java 8 terá algo equivalente, consulte Projeto Lambda .

Ele possui extensões LINQ to Objects do Enumerable, como animais . Mas, para coisas LINQ mais complicadas, como Expression e ExpressionTree (elas são necessárias para o LINQ to SQL e outros provedores LINQ, se eles desejam fornecer algo otimizado e real), ainda não há nenhum equivalente, mas talvez veremos isso no futuro :)

Mas acho que não haverá nada como consultas declarativas em Java no futuro.

Ebrahim Byagowi
fonte
2

Não existe esse recurso no java. Ao usar a outra API, você obterá esse recurso. Como suponha que tenhamos um objeto animal contendo nome e id. Temos um objeto de lista com objetos de animais. Agora, se queremos obter todo o nome do animal que contém 'o' do objeto da lista. podemos escrever a seguinte consulta

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

A instrução Query acima listará os animais que contêm o alfabeto 'o' em seu nome. Mais informações, visite o blog a seguir. http://javaworldwide.blogspot.in/2012/09/linq-in-java.html

Vishnu
fonte
2

Confira tiny-q . (Observe que você não pode baixá-lo no momento.)

Aqui está um exemplo adaptado no link acima:

Primeiro, precisamos de uma coleção de alguns dados, digamos, um conjunto de strings

String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };

Agora queremos selecionar apenas as strings que começam com "b":

Query<String> stringsStartingWithB = new Query<String>(strings).where(
    new Query.Func<String, Boolean>(){
        public Boolean run(String in) {
            return in.startsWith("b");
        }
    }
);

Nenhum dado real foi movido copiado ou algo parecido; eles serão processados ​​assim que você começar a iterar:

for(String string : stringsStartingWithB ) {
    System.out.println(string);
}
t90
fonte
1

JaQu é o equivalente em LINQ para Java. Embora tenha sido desenvolvido para o banco de dados H2, ele deve funcionar para qualquer banco de dados, pois usa o JDBC.

Basil Musa
fonte
1

Talvez não seja a resposta que você está procurando, mas se alguma parte do seu código precisar de muito trabalho em coleções (pesquisa, classificação, filtragem, transformações, análises), você pode considerar escrever algumas aulas no Clojure ou Scala .

Devido à sua natureza funcional, é melhor trabalhar com coleções. Não tenho muita experiência com o Scala, mas com o Clojure você provavelmente encontraria um Linq mais poderoso ao seu alcance e, uma vez compiladas, as classes que você produziria se integrariam perfeitamente ao restante da base de código.

pistacchio
fonte
1
Groovy ou jRuby também seriam candidatos viáveis, pois todos eles têm uma natureza muito mais funcional.
Cdeszaq
1

Um usuário anônimo mencionou outro, Diting :

Diting é uma biblioteca de classes que fornece recursos de consulta em coleções através de métodos encadeados e interface anônima como Linq no .NET. Diferentemente da maioria das outras bibliotecas de coleções, aqueles que estão usando métodos estáticos precisam repetir a coleção inteira, Diting fornece uma classe Enumerable principal, que contém métodos encadeados diferidos para implementar a consulta na coleção ou matriz.

Métodos suportados: any, cast, contact, contém, count, distinto, elementAt, exceto, first, firstOrDefault, groupBy, interset, join, last, lastOrDefault, ofType, orderBy, orderByDescending, reverse, select, selectMany, single, singleOrDefault, skip , skipWhile, take, takeWhile, toArray, toArrayList, union, where

Rup
fonte
1

Agora eu li e comecei a ler como linq, mas mais simples e mais ilegível. mas o scala pode rodar no linux, sim? csharp precisa mono.

Gêmeos
fonte
1
O Scala precisa de um tempo de execução Java para ser executado: ele não necessariamente funcionará em uma instalação simples do Linux, dependendo de quais componentes você instala.
Rup 03/03
@Rup há totalmente compatível JRE para o GNU / Linux, e Mono é não um totalmente compatível implementação do .NET.
Exibir nome
@ Sarge Esse não era o meu ponto, mas o Mono roda LINQ o suficiente, não é? Além disso, agora existe o .Net Core da Microsoft para Linux .
Rup
(GNU /) O Linux não é a única plataforma além do Windows, e o JRE existe para uma grande variedade de plataformas. O Mono não implementa tudo totalmente, por exemplo, não há WPF.
Exibir nome
0

Havia a linguagem de programação Pizza (uma extensão Java) e você deveria dar uma olhada nela. - Utiliza o conceito de "interfaces fluentes" para consultar dados de maneira declarativa e, em princípio, idêntico ao LINQ sem expressões de consulta (http://en.wikipedia.org/wiki/Pizza_programming_language). Mas, infelizmente, não foi buscado, mas teria sido uma maneira de obter algo semelhante ao LINQ no Java.

Nico
fonte
1
Claro que foi perseguido, mas não com o nome "Pizza". Os genéricos do Pizza foram mesclados ao GJ, que se tornou o compilador de referência do Java 1.3 (embora os genéricos estivessem ocultos atrás de uma flag até 1,5). Enquanto isso ... o restante das idéias, mais algumas extras, tornou-se Scala.
Kevin Wright
Obrigado por essa informação, é claro que Scala é um bom ponto aqui. Mas essas habilidades não foram integradas à linguagem Java. Você pode usar a linguagem Scala para implementar o bom código de consulta e usar o binário resultante e depois em Java.
Nico
Consulte também o ONGL em commons.apache.org/proper/commons-ognl , que está em uso e ainda está sendo mantido.
Nico