【问题标题】:Is there something like LINQ for Java? [closed]有没有类似 LINQ for Java 的东西? [关闭]
【发布时间】:2011-01-01 18:19:28
【问题描述】:

开始用 C# 学习 LINQ。
尤其是 LINQ to Objects 和 LINQ to XML。
我真的很喜欢 LINQ 的强大功能。

我了解到有一个名为 JLINQ 的 JavaScript 实现。
此外(正如 Catbert 发布的)Scala 将拥有 LINQ

您知道 LINQ 或类似的东西是否会成为 Java 7 的一部分吗?

更新:2008 年的有趣帖子 - LINQ for Java tool

【问题讨论】:

  • 我一直认为 LINQ 是“丑陋的”和错误的。它看起来很强大,你可以用它做一些大意大利面。毕竟,ORM 解决方案试图尽量减少使用类似 SQL 的语言。为什么要重新引入它们?
  • Bozho,LINQ 不仅仅是关于 ORM,它也是一个允许在 C# 中进行函数式编程的系统,尤其是在 linq2objects 和 lambda 表示法结合的情况下。对很多人来说,这是 LINQ 最有用的特性,而不是 ORM。
  • @Bozho:除了 AlecZorab 所说的 LINQ 的功能性质之外,类似 SQL 的语言的问题不在于它们本身的“SQLness”,它们的问题是它们通常被实现为基于字符串的嵌入式语言。无论如何,LINQ 的“SQLness”只是集合/关系操作的语法问题。它可以是 map、zip、filter、project 等关键字,而不是 select、where、group by 等,并且 LINQ 功能将是相同的,而不像 SQL 类语言。
  • 查看这个:github.com/nicholas22/jpropel-light,真实例子:new String[] { "james", "john", "john", "eddie" }.where(startsWith ("j")).toList().distinct();
  • 我还有我刚刚发布为 0.9 版的库,名为 Linq-A-Like。根据 Sobral 先生的回答,它唯一的答案是第 3 号子弹,使用 Java 的 lambda 和 Iterable 的变化性质,可以达到第 1 号。您可以在此处的 Maven 中心获得它:search.maven.org/…

标签: java linq scala closures java-7


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您可以尝试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');
       }
    

    【讨论】:

      【解决方案3】:

      重要的是要注意 LINQ 有四样东西:

      • 一元理解
      • 数据库集成
      • 类似 SQL 的语法
      • AST 操作

      刚听说过它的人可能会认为它只是数据库集成。使用过它的人可能会想到类似 SQL 的语法。那些真正深入研究的人会意识到它的一元理解方面,即使他们不知道它是什么。

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

      然而,一个人不需要特殊的语法来进行单子理解。它只是使它不受样板的影响。因此,具有适当泛型支持水平的语言可以立即使用它的这一方面。

      Scala 没有做的两件事。第一个是类似 SQL 的语法。这无济于事:SQL 语法在 Scala 中显得格格不入。我认为可以肯定地说大多数 Scala 程序员更愿意使用他们熟悉的东西——所谓的理解。

      另一件事是我还没有讨论过的,AST 操作。即能够操作已被编译器解析但尚未转换为字节码的代码,从而能够在生成完成之前对其进行更改。

      我认为这样的事情对 Scala 来说是一个福音——哎呀,任何语言。但是,话又说回来,我有 Forth 程序员的背景,在编译代码时修改代码的能力是上帝赋予的权利。 .Net 可以通过 LINQ 做到这一点,其他一些语言也可以,比如 Ruby。

      【讨论】:

      • @Daniel:+1 谢谢。有趣的。我不确定 .Net LINQ 是否能够进行 AST 操作。
      • AST 操作是表达式树的意义所在。请参阅stackoverflow.com/questions/1430738/…,进行更多讨论。
      • Scala 可以修改代码。它基于java。您可以使用 objectweb ASM 或 AspectJ 或 Spring 或一些自定义类加载器。
      • @kts 这无关紧要,此外,我从未说过 Scala 不能更改代码——尽管使用 objectweb ASM、AspectJ 或 Spring 不会归类为“Scala”。请再次阅读最后一段的下一段——我描述的能力不是改变已经编译的代码的能力,而是改变编译成的代码。
      【解决方案4】:

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

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

      【讨论】:

      • Querydsl 支持 SQL 作为后端。您可以从数据库模式生成查询类型。如果您想要更基于标准的方法,请考虑从您的模式生成符合 JPA 的域模型并使用 Hibernate 或其他一些 JPA 引擎。查询dsl:source.mysema.com/display/querydsl/Querydsl
      【解决方案5】:

      通过使用lambdaj 库,您可以找到声誉最高的用户,如下所示:

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

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

      【讨论】:

        【解决方案6】:

        看看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
        }
        

        【讨论】:

        • @catbert :我添加了一个示例来演示 Scala 的查询功能。 :)
        • 这个查询会被翻译成 SQL(如在 L2S 中)还是只适用于本地数据?
        • 适用于 Scala 的完整 LINQ API:github.com/nicholas22/propelS
        【解决方案7】:

        查看Quaere。它是一种类似于 LINQ 的 Java DSL,您可以将其作为库包含在内。示例:

        // 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

        【讨论】:

        • 对魔术弦的使用极其丑陋。也许有了 Java 7 的闭包,这会变得更好。
        • 然而,它不是类型安全的。例如,如果我拼错了u.getReputation(),它在编译时就不会被检测到。
        • @Daniel:是的,因此最后一段:“如果你输入错误,就不能反省那些向你展示问题”。
        【解决方案8】:

        由于当前缺少闭包,LINQ 在 Java 中会很困难。假设 Java 7 确实确实获得了相当紧凑的闭包支持和扩展方法,那么即使 LINQ 没有获得与查询表达式相当的功能,LINQ 也应该是可行的。

        Google Collections Library(现在为 1.0 - 但准备好后将替换为 Guava)包含许多必需的方法 - 我不会惊讶地看到 101 个类似 LINQ 的 API 很快出现因为闭包支持看起来相当最终。

        但是,我(目前)看不到 Java 获得表达式树之类的东西 - 所以我怀疑除非您有自定义编译,否则您将仅限于 LINQ to Objects。

        【讨论】:

        • @Jon Skeet:谢谢+1。 Java 闭包和 .Net 中的 LINQ 启用技术一样吗?
        • @Kb:闭包在 C# 中也称为 lambda,它们是支持 LINQ 的主要功能(扩展方法是另一个,但它们不太重要)。表达式树是 LINQ to SQL(和其他类似的东西)背后的力量,但是,就像 Jon 说的那样,Java 7 不需要这些。
        • 许多 Java 系统在加载时操纵字节码,而不是在编译期间操纵 AST,并且平台有许多挂钩来促进这一点。表达式树是一种实施策略,而不是必需品。
        猜你喜欢
        • 2012-10-21
        • 1970-01-01
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多