相当于Linq的最佳Java是什么?[关闭]


17

Java中是否有任何库可以提供Linq的功能?


1
我想您的意思是“ LINQ的语法”而不是“ LINQ的功能”。有许多库提供相同的功能:-)
mikera 2012年

相当于Java的很有可能是Groovy。在失去类型安全,虽然牺牲
蚊蚋

Answers:


20

为了获得完整的LINQ查询语法,您需要更新语言规范和支持新关键字和语法结构的编译器。这远远超出了大多数读者的理解。

为了在Java中获得类似于Linq的方法链语法,其外观和工作方式类似于C#中的语法,您需要Java不支持的两件事:扩展方法(可以像实例方法一样适用于实例的静态方法)和lambda表达式(匿名委托)。但是,如果您愿意承担一些额外的编码冗长性,则可以用现有的Java构造来欺骗这两者。我发现Java特别令人惊奇的一件事是能够创建匿名接口实现。应用于具有单个纯函数的接口,该函数基本上允许简单的匿名委托,前提是您具有所需的每个方法签名的接口。

因此,作为方法链的Linq的IEnumerable(对于Javaheads而言是Iterable)方面,应该可以在Java中近似;您基本上可以将其实现为控制Monad的流畅接口。您需要一个类似于的类LinqIterable,实现Iterable,该类:

  • 可以将任何Iterable输入转换为LinqIterable实例
  • 具有用于基本列表处理的方法,例如过滤,分组,串联,交集,排序等,这些方法可以接受单功能接口并生成新的LinqIterable,从而希望可以将这些方法链接为“惰性”。
  • 具有将LinqIterable转换回“具体”对象(例如ToList,ToArray,ToMap等)的方法

因此,您可能会定义一个“流利的”库,该库将允许诸如以下语句:

Map<String, Integer> results = Linq.FromIterable(sourceList)
                           .Where(new Predicate{public bool Op(SomeStruct in){return in.SomeString == "criteria";}})
                           .OrderBy(new Func{public String Op(SomeStruct in){return in.SomeOtherString;}})
                           .Select(new Func{public SomeOtherStruct Op(SomeStruct in){return new SomeOtherStruct(in.SomeOtherString, in.SomeInt);}})
                           .ToMap(new Func{public String Op(SomeOtherStruct in){return in.StringField;}},
                                  new Func{public Integer Op(SomeOtherStruct in){return in.IntField;}});

创建实际图书馆的工作远远超出了互联网问答的答案范围。我只是说有可能,并不容易。

表达式树不是火箭科学,但要实现.NET在该领域的功能,这将是一个重要的项目。您不仅需要构建表达式树的能力,还需要能够使用发出的字节码即时“编译”该树;我不知道Java的反射功能是否如此强大。


2
有趣的是,Java 8中都有足够的扩展方法和lambda表达式。也许LINQ即将来临?
lxs 2012年

4
好吧,如果您拥有扩展方法和lambda,那么您无需花费太多精力即可拥有.NET Linq的“可枚举”部分。就像我说的那样,仍然需要对Java规范进行更改,以允许进行Linq查询的关键字,但是老实说,在日常的Linq使用中,我并没有找到太多不那么容易的查询表示为方法链,并且编译器几乎将Linq语法转换为方法链(存在VS插件,可以在大多数查询和链之间进行1:1转换)。下一个真正的垫脚石将是表情树(可查询Linq)。
KeithS 2012年

8

看到:


1
您是否介意扩展这些资源的每种资源,为什么建议您在回答所提问题时使用这些资源?在Stack Exchange上不非常欢迎“仅链接的答案”
gnat

嗯,我想这是一个已经被回答过的问题-应该改写成重复的吗?
Martijn Verburg

1
@MartijnVerburg-我们无法将问题标记为跨站点重复。答案确实确实需要能够独立存在。
克里斯·

编辑,希望现在有所帮助。
Martijn Verburg


3

使用Scala原因如下

使用Scala的.NET端口。它使您可以完全本地访问.NET中的所有内容,其中显然包括LINQ。

如果不能,则可以尝试使用诸如functionjavalambdaj之类的库,但您不会真正接近LINQ。


1
Scala不包含没有库的Linq之类的东西。
乔纳斯(Jonas)

1
@Jonas:是吗?Java没有库中包含Linq之类的东西。
back2dos

@ back2dos:是的,这就是为什么您必须使用库进行回答的原因。
乔纳斯(Jonas)

1
@Jonas:Scala的标准库就像LINQ。或相反:LINQ只是C#的一组函数式编程习惯用法。在这里更多。
back2dos

@ back2dos:感谢您的出色链接,我可以自由地添加它。
2011年

2

我会将番石榴添加到库列表中,以帮助您实现LINQ的某些功能。

但是正如其他人指出的那样,纯Java没有等效的东西。


您介意进一步解释它的功能吗,为什么在回答所提问题时推荐它?在Stack Exchange上不太欢迎“仅链接的答案”
gnat

2

您可以使用Korma(DSL)来处理用Clojure编写的SQL查询。

语法非常简洁:

(select user
  (with address)
  (fields :firstName :lastName :address.state)
  (where {:email "korma@sqlkorma.com"}))

您可以通过导入相关的Clojure库并仅使用常规的Clojure / Java互操作从Java中轻松地调用它。


因此,这将模拟基于SQL的Linq,而不是基于对象的LINQ,对吗?
2012年

@Job:是的,它是为SQL设计的。尽管我看不出任何理由都无法对其进行扩展/调整。
mikera 2012年

2

Java中没有模仿linq的本机功能。但是,有几种API提供相同的功能。

例如,此博客文章有一个自定义jar来复制linq。
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html

这是帖子中API的示例用法:

假设我们有一个动物对象,其中包含名称和ID,并以的列表表示animals。如果要从列表中获取所有包含“ o”的动物名称animals,则可以编写以下查询

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

博客文章中引用了另外两个API: lambdaJjLinq


1
恐怕同时丢失静态类型检查和类成员是否存在的检查,对于像这样的调用而言,代价太高了where("getName", ...)
9000
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.