O que é equivalente em Java para LINQ?
O que é equivalente em Java para LINQ?
Respostas:
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
:-)
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();
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 .
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.
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
LINQ to Objects - O JAVA 8 adicionou a API Stream, que adiciona suporte para operações de estilo funcional em fluxos de valores:
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/
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.
from x in xs select x
e descoberto a resposta (não).
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.
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.
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 .
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.
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.
Eu tentei bibliotecas de goiaba do google. Ele tem um FluentIterable
que 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.
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);
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.
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.
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.
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.
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
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.
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
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);
}
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.
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.
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
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.
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.
Não há equivalente ao LINQ for Java. Mas há algumas API externas que se parecem com LINQ, como https://github.com/nicholas22/jpropel-light , https://code.google.com/p/jaque/
você pode experimentar esta biblioteca: https://code.google.com/p/qood/
Aqui estão alguns motivos para usá-lo: