什么是LINQ的Java等价物?
什么是Java相当于LINQ?
没有什么像Java的LINQ。
我开发了一个备用解决scheme, Coollection 。 很简单,专注于迭代集合的最常用操作。
像这样使用:
from(people).where("name", eq("Arthur")).first(); from(people).where("age", lessThan(20)).all(); from(people).where("name", not(contains("Francine"))).all();
Lambda现在在Java 8中以JSR-335的forms提供- 用于JavaTM编程语言的Lambdaexpression式
更新 : JDK8现已发布 ,其中包含项目lambda。 在Action中目前仍然是MEAP,所以值得抓一个Java 8的副本。
阅读Brian Goetz的有关lambdas的文章,了解如何在JDK8中实现lambdas,同时获得对stream,内部迭代,短路和构造函数引用的理解。还要查看上面的JSR以获取更多示例。
我已经写了一篇关于在JDK8中使用lambdas的所谓“箭头的力量 ”的优点的博客,同时NetBeans 8也很好地支持将构造转换为JDK8,我也在博客中介绍了如何使用NetBeans迁移到JDK 8 。
您可以使用lambdaj库以更易读的方式select集合中的项目(以及更多)
https://code.google.com/archive/p/lambdaj/
它比Quaere库有一些优点,因为它不使用任何魔术string,它是完全types安全的,在我看来它提供了一个更可读的DSL。
除非使用javacc来创build自己的等价物,否则不会find相当于LINQ的东西 。
直到那一天,当有人find一个可行的方式这样做,有一些很好的select,如
- jOOQ: http : //www.jooq.org
- JINQ: http : //www.jinq.org
- JaQue: http ://github.com/TrigerSoft/jaque
- JaQu: http ://www.h2database.com/html/jaqu.html
- Linq4j: https : //github.com/julianhyde/linq4j
- 问题: http ://quaere.codehaus.org/
- QueryDSL: http ://www.querydsl.com
- JSR-341: http : //java.net/projects/el-spec/pages/CollectionOperations
LINQ to Objects – JAVA 8添加了Stream API,它增加了对值stream的function风格操作的支持:
包java.util.stream
Java 8解释:将Lambdas应用于Java集合
LINQ to SQL / NHibernate /等。 (数据库查询) – 一种select是使用也使用新的JAVA 8function的JINQ,并于2014年2月26日发布在Github上: https : //github.com/my2iu/Jinq
Jinq为开发人员提供了一种简单自然的方式来编写Java数据库查询。 您可以像存储在集合中的普通Java对象那样对待数据库数据。 您可以遍历它们并使用普通的Java命令对其进行过滤,所有代码将自动转换为优化的数据库查询。 最后,LINQ风格的查询可用于Java!
JINQ项目网站: http : //www.jinq.org/
有一个叫做quaere的项目。
这是一个Java框架,增加了查询集合的能力。
注:根据作者,该项目不再被维护。
Java有很多LINQ等价物,请参阅这里作比较。
对于types安全的Quaere / LINQ样式框架,请考虑使用Querydsl 。 Querydsl支持JPA / Hibernate,JDO,SQL和Java Collections。
我是Querydsl的维护者,所以这个答案是有偏见的。
你可以使用scala,它在语法上是相似的,它实际上可能比linq更强大。
就像在2014年一样,我终于可以说LINQ终于在java 8中出现了。所以不需要再findLINQ的替代品了。
现在Java 8支持lambdas,可以创build与LINQ非常相似的Java API。
Jinq是Java的这些新的LINQ风格的库之一。
我是这个图书馆的开发者。 它基于五年的研究,使用字节码分析将Java转换为数据库查询。 类似于C#的D-LINQ是位于entity framework之上的查询层,Jinq能够充当位于JPA或jOOQ之上的查询层。 它支持聚合,组和子查询。 即使是Erik Meijer(LINQ的创造者)也承认Jinq 。
类似于 AC#的解决scheme是JaQue ,它为Java Lambdas提供expression式树。 最重要的是可以实现特定于领域的LINQ提供程序。
请参阅SBQL4J 。 它是与Java集成的types安全的强大的查询语言。 允许编写复杂和多重嵌套的查询。 有很多的操作符,可以在查询内部调用Java方法,所以构造函数也是如此。 查询被转换为纯Java代码(在运行时没有reflection),所以执行速度非常快。
编辑:那么,到目前为止SBQL4J这是Java语言的唯一扩展,它提供了类似于LINQ的查询function。 有一些像Quaere和JaQue这样有趣的项目,但是它们只是API的,而不是语法/语义的扩展,在编译的时候具有很强的types安全性。
我尝试了谷歌的guava-libraries 。 它有一个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那么简洁,但看起来很有趣。
https://code.google.com/p/joquery/
支持不同的可能性,
鉴于收集,
Collection<Dto> testList = new ArrayList<>();
types,
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"});
sorting (也可用于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<>();
可以join像,
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();
expression式
Filter<Dto> query = CQ.<Dto>filter() .from(testList) .where() .exec(s -> s.getId() + 1).eq().value(2);
只是为了添加另一个select:Java 6确实有使用javax.persistence.criteria包的types安全的数据库查询的解决scheme。
虽然我必须说,这不是真正的LINQ,因为用LINQ你可以查询任何IEnumerable。
有一个非常好的图书馆,你可以使用这个。
位于这里: https : //github.com/nicholas22/jpropel-light
Lambdas在Java 8之前是不可用的,所以使用它有点不同,并不自然。
这听起来像大家在这里谈论的Linq只是LinqToObjects。 我相信这只能提供现在已经可以在Java中完成的function,但却带有非常难看的语法。
我在.Net中看到的Linq的真正威力在于,lambdaexpression式可以在需要Delegate或者Expression的上下文中使用,然后被编译成合适的forms。 这就是允许LinqToSql(或LinqToObjects以外的任何东西)的工作,并允许它们具有与LinqToObjects相同的语法。
看起来上面提到的所有项目都只提供了LinqToObjects的function。 这让我担心LinqToSqltypes的function不在Java的范围之内。
对于基本的function集合,Java 8已经内置了它,大多数主要的非Java JVM语言都内置了它(Scala,Clojure等),并且可以为早期的Java版本添加库。
对于全语言集成访问SQL数据库,Scala(在JVM上运行)具有Slick
你可以试试我的库CollectionsQuery 。 它允许在对象集合上运行LINQ查询。 你必须通过谓词,就像在LINQ中一样。 如果您使用的是java6 / 7,则必须在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();
你也可以在Java8中使用它,或者在带有RetroLambda的旧java中使用它 ,它是gradle插件 ,那么你将会拥有新的花式语法:
List<String> names = Queryable.from(people) .filter(p->p.age>20) .map (p->p.name) .toList();
如果您需要运行数据库查询,您可以查看上面提到的JINQ,但不能通过RetroLambda移植回来,以便使用序列化的lambdaexpression式。
对于LINQ(LINQ to Objects),Java 8将具有相同的function,请参阅Project Lambda 。
它具有Enumerable的LINQ to Objects扩展,比如stuffs 。 但是对于像Expression和ExpressionTree这样更复杂的LINQ的东西(如果他们想提供一些优化和真实的东西的话,这些是LINQ to SQL和其他LINQ提供者所需要的),没有任何等价的东西,但是也许我们会在将来看到:)
但是我不认为将来会有类似于Java的声明性查询。
java中没有这样的function。 通过使用其他API,您将获得此function。 就像我们有一个动物对象包含名称和ID。 我们有名单对象有动物对象。 现在,如果我们想从列表对象中获取包含“o”的所有动物名称。 我们可以写下面的查询
from(animals).where("getName", contains("o")).all();
查询语句上方将列出名称中包含“o”字母的动物列表。 更多信息请通过以下博客。 http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
看看小q 。 (请注意,您目前无法下载。)
以下是一个适用于上述链接的示例:
首先,我们需要收集一些数据,比如一组string
String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };
现在我们只想select以“b”开头的string:
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); }
JaQu是Java的LINQ等价物。 虽然它是为H2数据库开发的,但它应该可以用于任何数据库,因为它使用JDBC。
也许不是你希望得到的答案,但是如果你的某些代码需要在集合上进行繁重的工作(search,sorting,过滤,转换,分析),你可以考虑在Clojure或Scala中编写一些类。
由于它们的function性,与collections品合作是他们最擅长的。 我对Scala并没有太多的经验,但是在Clojure中,你可能会发现一个更强大的Linq,一旦编译完成,你所生成的类将会与代码库的其余部分整合在一起。
一位匿名用户提到另外一个, Diting :
Diting是一个类库,通过可链式方法和匿名接口(如.NET中的Linq)为集合提供查询function。 与大多数其他集合库不同的是,使用静态方法需要迭代整个集合,Diting提供了一个核心Enumerable类,它包含了在集合或数组上实现查询的可链式方法。
支持的方法:any,cast,contact,contains,count,distinct,elementAt,first,firstOrDefault,groupBy,interset,join,last,lastOrDefault,ofType,orderBy,orderByDescending,reverse,select,selectMany,single,singleOrDefault,skip ,skipWhile,take,takeWhile,toArray,toArrayList,union,where
Scala.Now我明星读了它,发现它像linq,但更简单,更难以理解。 但斯卡拉可以在Linux上运行,是吗? csharp需要单声道。
有编程语言披萨(一个Java扩展),你应该看看它。 – 它使用“stream畅的接口”的概念以声明的方式查询数据,这与LINQ没有查询expression式(http://en.wikipedia.org/wiki/Pizza_programming_language)原则上相同。; 但是,唉,它并没有被追求,但它可能是一种类似于LINQ到Java的方法。
对于Java来说,并不是真正的“Linq to SQL”。 但接近它的东西。 查询DSL