是否有类似LINQ for Java的东西?

时间:2010-01-05 18:22:11

标签: java linq scala closures java-7

开始用C#学习LINQ 特别是LINQ to Objects和LINQ to XML 我非常喜欢LINQ的力量。

我了解到有一些名为JLINQ的Jscript实现 另外(正如Catbert发布​​的那样)Scala将有LINQ

你知道LINQ或类似的东西是否会成为Java 7的一部分吗?
更新:2008年有趣的帖子 - LINQ for Java tool

8 个答案:

答案 0 :(得分:33)

查看Scala,它是功能强大的函数式编程语言,但与Java类似,可在Java平台上运行。

在Scala中,可以使用与LINQ中基本相同的代码构造,尽管在C#或VB中没有特殊的查询理解语法。

编辑:

以下是Scala查询功能的一个示例:

// Get all StackOverflow users with more than 20,000 reputation points.
val topUsers = for{
    u <- users
    if u.reputation > 20000
} yield u;

println ("Users with more than 20,000 reputation:")
for (u <- topUsers) {
    println u.name
}

答案 1 :(得分:30)

重要的是要注意LINQ有四件事:

  • Monadic comprehension
  • 数据库集成
  • 类似SQL的语法
  • AST操纵

刚刚听说过它的人可能会把它简单地想象为数据库集成。与之相关的人可能会想到类似SQL的语法。那些真正挖掘过的人会意识到它的monadic理解方面,即使他们不知道它是什么。

例如,如果一个人使用Scala,那么它没有其他三个就具有monadic理解力。有一个名为ScalaQuery的库,它通过monadic理解提供数据库集成(这样做的内在能力是monad很酷的主要原因)。我认为另一个名为ScalaQL的项目打算提供几乎相同的东西,但是使用编译器插件来增强它。我不知道Miguel Garcia你提到的工作,但是,看到他已经完成的其他事情,我很高兴。

然而,不需要特殊的语法来进行monadic理解。它只是通过样板制作整洁。因此,具有适当级别的泛型支持的语言可以立即使用它。

Scala没做的两件事。第一种是类似SQL的语法。这无济于事:SQL语法在Scala中看起来不合适。我认为可以肯定地说,大多数Scala程序员宁愿选择他们熟悉的东西 - 所谓的理解。

另一件事是我尚未讨论过的,AST操纵。这是能够操作已由编译器解析但尚未在字节代码中转换的代码的能力,从而授予在生成完成之前更改它的能力。

我认为这样的事情对Scala来说是一个福音 - 对任何语言而言都是如此。但是,再一次,我有一个Forth程序员的背景,在编译时改变代码的能力是上帝赋予的权利。 .Net可以通过LINQ实现,其他语言也可以,例如Ruby。

答案 2 :(得分:13)

由于目前缺少关闭,LINQ在Java方面会很难。假设Java 7确实 获得了相当紧凑的闭包支持和扩展方法,LINQ在“点符号”方面应该是可行的,即使它没有得到相当于查询表达式。

Google Collections Library(现在为1.0 - 但在准备就绪后由Guava替换)包含许多必需的方法 - 我不会对看到类似LINQ的API感到惊讶一旦闭合支撑看起来合理,最终就会出现。

我现在看不到(现在)Java得到类似表达式树的东西 - 所以我怀疑你将被限制为LINQ to Objects,除非你有自定义编译。

答案 3 :(得分:11)

通过使用lambdaj库,您可以找到最佳信誉用户:

List<User> topUsers = 
    select(users, having(on(User.class).getReputation(), greaterThan(20000)));

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

答案 4 :(得分:10)

结帐Quaere。它是一个类似LINQ的DSL for Java,可以作为库包含在内。例如:

// Get all StackOverflow users with more than 20,000 reputation points.
Iterable<User> topUsers = from("u").in(entityManager.entity(User.class)).
    where(gt("u.getReputation()", 20000)).
    select("u");

System.out.println("Users with more than 20,000 reputation:");
for (User u : topUsers) {
    System.out.println(u.getName());
}

但是,请注意,Java没有类似于扩展方法的概念。无论Quaere是什么,几乎都是你所困扰的;如果您需要创建自己的特殊实用程序,它们可能必须位于单独的实用程序类中(ick)。

另外,因为Java&lt; 7没有原生的闭包,你被串在引用的东西上,如果你输入错误的东西,你的IDE就无法反省那些向你展示问题的东西。 (更聪明的IDE可能能够处理这个缺点,但是,如果有人要为Quaere编写内省插件。)

答案 5 :(得分:4)

您可以尝试diting在集合上实现可链式查询方法。

   Integer[] values = new Integer[] {0,1,2,3,4,5,6,7,8,9,10};

   Enumerable<Integer> query = new Enumerable<Integer>(values).where(new Predicate<Integer>(){

    @Override
    public boolean evaluate(Integer value) throws Exception {
        return value % 2 == 0;
    }});

   for(Integer i : query)
   {
       System.out.write(i);
       System.out.write('\n');
   }

答案 6 :(得分:3)

CQEngine或Collection Query Engine http://code.google.com/p/cqengine/似乎非常有前景。虽然没试过。它允许您在集合上构建索引并查询它们。应该很快。

答案 7 :(得分:2)

JVM上有没有像LINQ-2-SQL一样简单的东西?我想使用一些工具从DB方案生成实体(类),并使用它们直接与DB交互。有没有XML的解决方案吗?我不想要注释这些类。在.NET中,该工具称为sqlmetal。它可以说是一种预生成器,可以生成所有的DB类。

一旦完成,我认为使用Scala的内置语言结构会相当容易。