LINQ的Java等效项是什么?[关闭]


820

LINQ的Java等效项是什么?


4
这些似乎是LINQ to SQL。
SLaks 2011年

8
请检查以下内容:github.com/nicholas22/jpropel-light,真实示例:new String [] {“ james”,“ john”,“ john”,“ eddie”} .where(startsWith(“ j”))。toList ()。不同();
NT_

1
Java ppl仍然使用Linq可以解决的多个语句和foreach循环
om471987

1
同样适用于具有完整LINQ API的Scala:github.com/nicholas22/propelS
Scooterville,2012年

4
@craastad作为一个现在经常被困在Java世界中的.NET家伙,我感到您很痛苦。不过,您应该尝试使用Scala-一流的函数/闭包,以进行全面理解(与LINQ的查询语法不同,但在许多相同的情况下很有用),统一的类型系统,类型推断,一些用于通用类型擦除的便捷解决方法...全部在JVM上运行,并与Java互操作。再加上一堆像模式匹配,选项类型等其它功能善
添古德曼

Answers:


808

没有像LINQ for Java这样的软件。

...

编辑

现在,使用Java 8向我们介绍了Stream API,这在处理集合时是一种类似的事情,但与Linq不太一样。

如果它是您正在寻找的ORM,例如Entity Framework,那么您可以尝试使用Hibernate

:-)


9
计划中有什么吗?融入语言?这是JCP号码吗?等
-Cheeso

6
确实如此,尽管使LINQ
如此出色

11
抱歉,“非常真实”适用于280Z28。我不知道是否有JCP。考虑到JCP的工作速度,我无法屏住呼吸,LINQ不得不对C#语言进行几处更改。
09年

12
这是不正确的。请参阅:stackoverflow.com/questions/10879761/...
Scooterville

23
LINQ是规范,而不是实现。Lambda表达式是LINQ的一部分。试图将LINQ移植到Java的所有项目都是针对特定场景(SQL,Objects ...)的实现,但并未涵盖LINQ的主要目标:将语言查询集成到代码中。因此,目前还没有真正的替代方案或倡议可以被视为替代方案。
sesispla

154

还有一个替代解决方案Coollection

Coolection并没有伪装成新的lambda,但是我们被旧的旧Java项目所包围,这个lib可以为您提供帮助。它的使用和扩展非常简单,仅覆盖集合中最常用的迭代操作,如下所示:

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

7
列名的字符串,这意味着编译器和IDE自动完成功能不会对拼写错误有所帮助,并且很难进行重构。有任何改变的计划吗?
Ekevoo 2014年

2
嗨,Ekevoo。我认为那太可怕了,我尝试过一段时间。但是目前,在Java 8中,Coollection是一个已弃用的库。也许对最早的项目很有用……您怎么看?
19WAS85

1
@WagnerAndrade上一次提交是5-6年前。我假设该功能在很大程度上已被Java 8取代了?另外,很酷的名字:)
Abdul

145

Lambdas现在JSR-335的形式在Java 8中可用-JavaTM编程语言的Lambda表达式

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

请阅读Brian Goetz的有关lambda的文章,以便对在JDK8中如何实现lambda有所体会,同时也了解流,内部迭代,短路和构造方法参考。此外,请查看上述JSR以获得更多示例。 。

我已经写了一个博客,介绍了在JDK8中使用lambda的一些优点,称为“箭头的力量”,而且NetBeans 8对将结构转换为JDK8 也提供了强大的支持,我也写了博客介绍如何使用NetBeans迁移到JDK 8


lambda是否也计划在Java 7中使用?发生了什么?
BlueRaja-Danny Pflughoeft

7
甲骨文收购了Sun(面无表情)。Java 7花费的时间太长(5年),因此lambda错过了入围名单,这对大众来说实在令人失望。话虽这么说,甲骨文确实看起来像在接球,我认为我们计划于明年10月8日使用Java。
Brett Ryan

1
请注意,Lambda状态已再次更新,现在涵盖流,内部迭代,短路和构造函数引用。我建议大家阅读新文件。
布雷特·瑞安

6
Lambda表达式只是LINQ的一小部分。
sesispla 2013年

4
@NeWNeO,如果您使用C#引用查询语言,那么可以,Java并没有类似的东西,但是以我的经验,大多数经验丰富的C#开发人员都喜欢lambda语法而不是查询语言。但是,如果您以LINQ-to-Entities为例,那么您会发现java中的lambda可以启用此功能以及更多功能。Java 8启用了此功能,例如防御方法
Brett Ryan

119

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

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

它比Quaere库具有一些优势,因为它不使用任何魔术字符串,它是完全类型安全的,而且我认为它提供了更具可读性的DSL。


6
这是好的,但它是从大约是构建查询和SQL再次执行,XML,收集等相去甚远
bytebender

为什么在我的android项目中的自定义类上使用lambdaj select时,为什么会出现java.lang.ExceptionInInitializerError?
topwik 2012年

1
+1对于那些不关心SQL / XML而只希望更轻松地访问集合的人来说,这确实是个好选择。
ashes999 2014年

101

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

直到有人找到可行的方法的那一天,还有一些不错的选择,例如


github.com/TrigerSoft/jaque找到了这种方法,并允许创建表达式树。与Java 8 Lambda结合使用时,任何LINQ容量都可以像.Net一样实现。
康斯坦丁·特里杰


49

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

软件包java.util.stream

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

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

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

JINQ项目站点:http : //www.jinq.org/


即使Stream API与LINQ最接近,也不确定为什么读者没有关注您的答案!
拉菲德2014年

3
与LINQ相比,Streams API是个坏笑话。
安德烈·里内(AndreiRînea),

1
对不起,人,不是要无礼。在使用Streams API击败我之后,我一直在寻找LINQ等效产品。我只是想说那不是真正的对等,仅此而已。
AndreiRînea'17

1
@AndreiRînea您是否在寻找等效的LINQ提供程序(LINQ to XML,LINQ to JSON,LINQ to NHibernate等)?
拉兹万·弗拉维斯·熊猫

2
我需要的只是对集合进行分组和最大化的一种方法。我最终成功了,但是付出了很多努力和太多的代码。
AndreiRînea'17

29

有一个名为quaere的项目。

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

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


2
Quaere看起来提供了LINQ所提供的功能,但问题是“等同”的问题
AgileJon

6
因此,如果不是直接等效项,它就像 LINQ?至少听起来很有帮助
Brian Agnew

3
@AgileJon:如果他真的是等效的话,他不会问。他可以from x in xs select x打出并找到答案(否)。
kizzx2 2011年

18

Java有许多LINQ等效项,请参见此处进行比较。

对于类型安全的Quaere / LINQ样式框架,请考虑使用Querydsl。Querydsl支持JPA /休眠,JDO,SQL和Java集合。

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


6
“相似框架”链接已失效。您还有同等的页面吗?
卢卡斯·埃德

我们什么时候可以获得QueryDSL书?甚至负担得起的培训选择?您的支持链接404s。
凯文2014年

16

您可以使用scala,它的语法相似,并且实际上可能比linq更强大。


1
Esp。Scala的“理解力”。
Nico

10

就像2014年一样,我终于可以说LINQ终于出现在Java 8中了,因此不再需要寻找LINQ的替代方案。


9

既然Java 8支持lambda,则可以创建与LINQ非常相似的Java API。

Jinq是这些新的Java LINQ样式库之一。

我是这个图书馆的开发商。它基于使用字节码分析将Java转换为数据库查询的五年研究成果。与C#的D-LINQ是位于实体框架之上的查询层类似,Jinq能够充当位于JPA或jOOQ之上的查询层。它支持聚合,组和子查询。甚至Erik Meijer(LINQ的创建者)也承认Jinq


8

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

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


6
您可能要提及您在项目中的角色。
托尔比约恩Ravn的安徒生


7

我尝试了来自谷歌的番石榴图书馆。它有一个FluentIterable我认为这是接近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简洁,但看起来很有趣。


7

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

5

您可以尝试我的库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();

如果您需要运行数据库查询,则可以如上所述查看JINQ,但是RetroLambda不能将其反向移植,只能使用序列化的lambda。





4

听起来每个人都在谈论的Linq只是LinqToObjects。我认为,这些功能仅提供了Java现在已经可以完成的功能,但是语法却非常丑陋。

我看到的.net中Linq的真正功能是,可以在需要委托或表达式的上下文中使用lambda表达式,然后将其编译成适当的形式。这就是使LinqToSql之类的东西(或LinqToObjects之外的其他东西)能够工作的原因,并使它们具有与LinqToObjects相同的语法。

看起来上面提到的所有项目都仅提供LinqToObjects的功能。这让我感到,LinqToSql类型的功能对于Java而言并不是遥不可及的。


4

对于基本功能集合,Java 8内置了它,大多数主要的非Java JVM语言都内置了它(Scala,Clojure等),并且您可以在早期Java版本上添加库。

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


3

对于LINQ(对象的LINQ),Java 8将具有等效功能,请参阅Project Lambda

它具有Enumerable的LINQ to Objects扩展(stuffs)。但是对于诸如Expression和ExpressionTree之类的更复杂的LINQ (如果LINQ to SQL和其他LINQ提供程序想要提供优化和真实的功能,这些是LINQ所需要的),目前还没有任何等效的方法,但是也许将来我们会看到:)

但是我不认为将来会有类似Java的声明式查询之类的事情。


2

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

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

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


2

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

1

JaQu是LINQ的Java等效项。尽管它是为H2数据库开发的,但由于它使用JDBC,因此它适用于任何数据库。


1

也许不是您想要的答案,但是如果您的代码中的某些部分需要对集合进行大量工作(搜索,排序,过滤,转换,分析),则可以考虑在ClojureScala中编写一些类。

由于其功能性,最擅长使用集合。我没有使用Scala的丰富经验,但是使用Clojure可能会发现唾手可得的功能更强大的Linq,并且一旦编译,生成的类将与其余代码库无缝集成。


1
Groovy或jRuby也将是可行的候选人,因为它们都具有更多的功能性。
cdeszaq 2011年

1

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

Diting是一个类库,它通过可链接的方法和.NET中的Linq等匿名接口提供对集合的查询功能。与大多数其他使用静态方法的集合库不同,这些静态库需要迭代整个集合,而Diting提供了一个核心的Enumerable类,其中包含有延迟的可链接方法,以对集合或数组执行查询。

支持的方法:任何,强制转换,联系,包含,计数,不同,elementAt,除了first,firstOrDefault,groupBy,interset,join,last,lastOrDefault,ofType,orderBy,orderByDescending,反向,select,selectMany,单,singleOrDefault,跳过,skipWhile,take,takeWhile,toArray,toArrayList,union,


1

Scala.Now我开始阅读它,发现它像linq一样,但更简单,更不可读。但是scala可以在linux上运行,是吗?csharp需要单声道。


1
Scala需要Java运行时才能运行:它不一定会在裸露的Linux安装上运行,这取决于安装的组件。
Rup 2014年

@Rup有一个完全兼容的GNU / Linux JRE,而Mono 不是一个完全兼容的 .NET实现。
显示名称

@Sarge这不是我的意思,但是Mono能很好地运行LINQ是不是?此外,现在还有Microsoft自己的.Net Core for Linux
Rup

(GNU /)Linux并非Windows之外的唯一平台,并且JRE存在于多种平台上。Mono不能完全实现所有功能,例如,没有WPF。
显示名称

0

有编程语言Pizza(Java扩展),您应该看看它。-它使用“流利接口”的概念以声明性的方式查询数据,并且在原则上与不带查询表达式的LINQ(http://en.wikipedia.org/wiki/Pizza_programming_language)相同。但是可惜的是,它并没有被人们追捧,但这将是将类似于LINQ的东西引入Java的一种方法。


1
可以肯定的是,它的名字不是“ Pizza”。Pizza的泛型被合并到GJ中,GJ随后成为Java 1.3参考编译器(尽管泛型一直被隐藏在1.5之前的标志后面)。在此期间,其余的想法以及其他一些想法变成了Scala。
凯文·赖特

感谢您提供的信息,Scala当然在这里很不错。但是这些功能没有集成到Java语言中。您可以使用Scala语言实现漂亮的查询代码,然后使用Java生成的二进制文件。
Nico 2012年

另请参阅commons.apache.org/proper/commons-ognl上的 ONGL(正在使用并且仍在维护中)。
尼科


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.