LINQ的Java等价物是什么?


没有什么比LINQ for Java更好的了。

...

Edit

现在,在Java8中,我们介绍了StreamAPI,这在处理集合时是一种类似的事情,但它与Linq不同。

如果您正在寻找的是ORM,比如实体框架,那么您可以尝试Hibernate

:-)


有一个叫做quaere的项目。

这是一个Java框架,它增加了查询集合的能力。

注:根据作者的说法,该项目已不再维护。


Java有许多LINQ等价物,请参阅此处进行比较。

对于类型安全的Quaere/LINQ风格框架,请考虑使用Querydsl。Querydsl支持JPA/Hibernate、JDO、SQL和Java集合。

我是Querydsl的维护者,所以这个答案有失偏颇。


您可以使用lambdaj库以更易读的方式选择集合中的项目(以及更多)

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

它比Quaere库有一些优势,因为它不使用任何魔法字符串,它完全是类型安全的,在我看来,它提供了一个更可读的DSL。


Java LINQ to SQL实现。与.NET LINQ相比,提供了完整的语言集成和更大的功能集。


参见SBQL4J。它是与Java集成的类型安全的强查询语言。允许编写复杂和多重嵌套查询。有很多运算符,Java方法可以作为构造函数在查询中调用。查询被转换为纯Java代码(在运行时没有反射),因此执行速度非常快。

编辑:到目前为止,SBQL4J是Java语言的唯一扩展,它提供了类似LINQ的查询功能。有一些有趣的项目,比如Quaere和JaQue,但它们只是API,而不是编译时具有强类型安全性的语法/语义扩展。


有一个替代的解决方案,库利选择。

Coolection并没有假装是新的lambda,但是我们周围都是旧的遗留Java项目,这个库将对我们有所帮助。它的使用和扩展非常简单,只涵盖集合上最常用的迭代操作,例如:

from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();

只需添加另一个备选方案:Java6确实有一个使用javax.persistence.ccriteria包的类型安全数据库查询解决方案。

尽管我必须说,这不是真正的LINQ,因为使用LINQ可以查询任何IEnumerable。


除非您使用javacc创建自己的等效程序,否则您将找不到LINQ的等效程序。

在有人找到可行的方法之前,还有一些好的选择,比如

jOOQ公司金克牌手表JaQue公司JaQu公司Linq4j公司码头(不再维护)查询DSLJSR-341型


JaQu是Java的LINQ等价物。虽然它是为H2数据库开发的,但它应该适用于任何数据库,因为它使用JDBC。


有编程语言Pizza(一个Java扩展),你应该看看它。-它使用“流畅接口”的概念以声明方式查询数据,这在原则上与LINQ w/o查询表达式相同(http://en.wikipedia.org/wiki/Pizza_programming_language). 但遗憾的是,这并没有被追求,但这将是将类似LINQ的东西引入Java的一种方式。


Lambdas现在以JSR-335的形式在Java8中提供-用于JavaTM编程语言的Lambda表达式

更新:JDK8现已发布,其中包含lambda项目。值得一提的是,目前仍然是MEAP的Java 8 in Action。

阅读Brian Goetz关于lambdas的文章,了解如何在JDK8中实现lambdas,同时了解流、内部迭代、短路和构造函数引用。。还要查看上面的JSR以获得更多示例。

我写了一篇关于在JDK8中使用lambdas的一些优点的博客,名为the Power of the Arrow,NetBeans 8也非常支持将构造转换为JDK8,我也写了一个关于使用NetBeans迁移到JDK8的博客。


有一个非常好的图书馆,你可以用来做这个。

位于此处:https://github.com/nicholas22/jpropel-light

Lambdas要到Java8才能使用,所以使用它有点不同,感觉不太自然。


您可以使用scala,它在语法上类似,实际上可能比linq更强大。


也许不是你所希望的答案,但如果你的代码的某些部分需要在集合上做大量工作(搜索、排序、过滤、转换、分析),你可以考虑用Clojure或Scala编写一些类。

由于其功能性,使用集合是他们最擅长的。我对Scala没有太多经验,但使用Clojure,您可能会发现一个更强大的Linq,一旦编译,您将生成的类将与其他代码库无缝集成。


查看tiny-q。(请注意,您当前无法下载。)

下面是一个适用于上述链接的示例:

首先,我们需要一些数据的集合,比如一组字符串

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

现在我们只选择以“b”开头的字符串:

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

没有实际的数据被复制或类似的东西,一旦你开始迭代,它就会被处理:

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

听起来大家在这里谈论的Linq只是LinqToObjects。我认为,它只提供了今天已经可以用Java实现的功能,但语法非常难看。

我认为Linq在.Net中的真正优势在于,lambda表达式可以在需要委托或表达式的上下文中使用,然后将其编译为适当的形式。这使得LinqToSql(或LinqToObjects以外的任何东西)这样的东西能够工作,并允许它们具有与LinqToObject相同的语法。

看起来上面提到的所有项目都只提供LinqToObjects的功能。这让我觉得LinqToSql类型的功能对于Java来说还没有出现。


对于LINQ(LINQ to Objects),Java 8将有类似的功能,请参见Project Lambda。

它具有Enumerable的LINQ to Objects扩展,如填充。但对于更复杂的LINQ,如表达式和ExpressionTree(如果LINQ to SQL和其他LINQ提供程序希望提供优化和真实的内容,则需要这些),目前还没有任何等效的,但我们可能会在未来看到:)

但我认为未来在Java上不会有类似声明式查询的东西。


一位匿名用户提到了另一个,Diting:

Diting是一个类库,它通过可链接方法和匿名接口(如.NET中的Linq)提供对集合的查询功能。与大多数其他使用静态方法的集合库不同,Diting提供了一个核心Enumerable类,该类包含可链接方法以实现对集合或数组的查询。支持的方法:any、cast、contact、contains、count、distinct、elementAt、except、first、firstOrDefault、groupBy、interset、join、last、lastOrDefault、ofType、orderBy、orderByDescending、reverse、select、selectMany、single、singleOrDefault、skip、skipWhile、take、takeWhile、toArray、toArrayList、union,其中


java中没有这样的功能。通过使用其他API,您将获得此功能。就像假设我们有一个包含名称和id的动物对象。我们有包含动物对象的列表对象。现在,如果我们想从列表对象中获取包含“o”的所有动物名称。我们可以编写以下查询

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

上面的Query语句将列出名称中包含“o”字母的动物。更多信息请浏览以下博客。http://javaworldwide.blogspot.in/2012/09/linq-in-java.html


对于基本的函数集合,Java8内置了它,大多数主要的非Java JVM语言(Scala、Clojure等)都内置了它。

对于SQL数据库的完全语言集成访问,Scala(在JVM上运行)具有Slick


我尝试了谷歌的番石榴图书馆。它有一种流利的语言,我认为它接近LINQ。另请参见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();
        }
    });

似乎是一个广泛的Java库。当然没有LINQ简洁,但看起来很有趣。


对于Java来说,并不是真正的“Linq to SQL”。但有点接近。查询DSL


没有与LINQ for Java等效的语言。但是有一些外部API看起来像LINQ,比如https://github.com/nicholas22/jpropel-light, https://code.google.com/p/jaque/


HQL(Hibernate查询语言)与.Net中的Linq非常相似


斯卡拉。现在我读了它,发现它像linq,但更简单,更不可读。但是scala可以在linux上运行,是吗?csharp需要单声道。


LINQ to Objects-JAVA 8添加了流API,它增加了对值流的函数式操作的支持:

包java.util.stream

Java 8解释:将Lambdas应用于Java集合

LINQ to SQL/Nibernate/等。(数据库查询)-一种选择是使用JINQ,它也使用了新的JAVA 8功能,于2014年2月26日在Github上发布:https://github.com/my2iu/Jinq

Jinq为开发人员提供了一种简单自然的数据库编写方法Java中的查询。您可以像对待普通Java对象一样对待数据库数据存储在集合中。您可以使用正常的Java命令,所有代码将自动转换为优化的数据库查询。最后,LINQ风格查询可用于Java!

JINQ项目现场:http://www.jinq.org/


您可以尝试此库:https://code.google.com/p/qood/

以下是使用它的一些原因:

轻量级:只有9个公共接口/类需要学习。类似SQL的查询:支持groupby、order by、left join、,公式等对于大数据:使用文件(QFS)而不是堆内存。尝试解决对象关系阻抗失配。


你可以试试我的图书馆CollectionsQuery。它允许在对象集合上运行类似LINQ的查询。您必须传递谓词,就像在LINQ中一样。如果您使用的是java6/7,则必须对接口使用旧语法:

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

您也可以在Java8中使用它,或者在带有RetroLambda和它的gradle插件的旧java中使用它。然后您将拥有新的花式语法:

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

如果您需要运行DB查询,那么可以查看JINQ,如上所述,但RetroLambda无法对其进行反向移植,因此无法使用序列化的Lambda。


与2014年一样,我终于可以说LINQ终于在java8中出现了。因此,不再需要寻找LINQ的替代品。


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

支持不同的可能性,

给定集合,

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

类型,

class Dto
{
    private int id;
    private String text;

    public int getId()
    {
        return id;
    }

    public int getText()
    {
        return text;
    }
}

滤器

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

而且

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

排序(也适用于Java 7)

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

分组(也适用于Java 7)

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

联接(也适用于Java 7)

鉴于

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

可以像,

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

表达

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

既然Java8支持lambdas,就可以创建与LINQ非常相似的JavaAPI了。

Jinq是这些新的LINQ风格的Java库之一。

我是这个库的开发人员。它基于五年来使用字节码分析将Java转换为数据库查询的研究。类似于C#的D-LINQ是一个位于实体框架之上的查询层,Jinq能够充当JPA或jOOQ之上的一个查询层。它支持聚合、组和子查询。就连埃里克·梅杰(LINQ的创始人)也承认了金克。


您可以使用Java Functional Utils转换与Android上的Java 1.7兼容的C#101 LINQ示例。


无耻的自插塞:你可以随时使用https://github.com/amoerie/jstreams

适用于Java 6及以上版本,非常适合Android开发。

它看起来很像Scala运算符、lodash、C#LINQ等。