【问题标题】:Quaere - Anyone using it yet? (LINQ to Objects for Java) [closed]Quaere - 有人在用吗? (LINQ to Objects for Java)[关闭]
【发布时间】:2009-07-08 07:59:41
【问题描述】:

我最初是一个 .NET 人,最近在 Java 中工作,发现我真的很想念 LINQ to Objects,特别是用于对集合执行过滤。

Stack Overflow 上的一些人回答了“LINQ for Java?”一个词的问题:

Quaere

但是,在网站上明确指出“Pre-Beta”,并且一年多来没有提交过他们的代码,所以我猜这个项目几乎已经死了。

是否有人实际使用它,和/或有任何使用经验?

第二个最常见的答案似乎是“使用 Google 收藏”。这是最合适的Java方式吗?

干杯

马蒂

【问题讨论】:

  • 对于 linq to objects 检查 github.com/nicholas22/jpropel-light,真实示例:new String[] { "james", "john", "john", "eddie" }.where( startsWith("j")).toList().distinct();

标签: java collections linq-to-objects


【解决方案1】:

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

http://code.google.com/p/lambdaj/

【讨论】:

  • +1 看起来很不错,谢谢你的链接。
  • 我个人完全不理解围绕 LINQ 的炒作,尤其是在看到 LambdaJ 做了什么(以及如何做!)之后。绝对值得 +1。
  • @Esko,将sort(persons, on(Person.class).getAge()) 与LINQ 的persons.OrderBy(x => x.Age) 进行比较。此外,LambdaJ 的效率相当低,正如他们的性能比较所证明的那样:code.google.com/p/lambdaj/wiki/PerformanceAnalysis。最后,这篇评论甚至还没有开始讨论 LINQ 中的表达式树,它允许将您的操作直接映射到数据库中。
  • @Kirk 你要我比较sort persons based on person's agepersons, order them by their age。其中哪一个听起来更正确? LambdaJ 也比本地方法慢,这并不奇怪,因为 LambdaJ 是建立在代理和反射之上的。至于 LINQ,因为它真的没有给我留下深刻印象,它需要结合类型推断之类的东西才能让它变得有趣。至于 SQL 预测之类的,好吧,我想这很重要,如果你仍在使用基于 SQL 的数据存储,我不是,所以我也没有真正看到这种好处。
  • @Esko,我对 sortOrderBy 这个词没有偏好。我确实有strong 偏好调用方法on 某物(表达式dot 表达式),而不是必须知道神奇的准全局“实用程序”方法比如sorton。至于它不会“给你留下深刻印象”,我猜你根本不使用.Net。 -- 因为没有人使用 .Net 避免使用 LINQ。
【解决方案2】:

Quaere 在 Java 中处于 LINQ 的先驱地位,但不是类型安全的,这是 LINQ 的要点之一。

Querydsl 是类型安全的,支持过滤、排序和投影集合。

它还支持对 JPA/Hibernate、JDO 和 SQL 后端的操作。

语法类似于SQL,不同的是基本顺序是from-where-list。

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

【讨论】:

    【解决方案3】:

    对于简单的 Linq To Objects,我认为在 Java 中可以做到的最好的事情是这样的:

    Vector<Integer> numbers = new Vector<Integer>();
    
    numbers.add(42);
    numbers.add(3);
    numbers.add(16);
    numbers.add(92);
    numbers.add(9);
    
    Iterable<Integer> filtered = new Where<Integer>(numbers) {
        protected boolean predicate(Integer i) { return i > 10; }
    };
    
    Iterable<String> converted = new Select<Integer, String>(filtered) {
        protected String select(Integer i) { return i.toString(); }
    };
    
    for (final String str : converted)
        System.out.println(str);
    

    请注意,我没有在一个表达式中将 WhereSelect 链接在一起。我可以将filtered 的定义插入它使用的一个地方,但这可能会使其(甚至)不那么可读。问题是缺少扩展方法和 lambdas。我们可以通过这些匿名类声明最接近 lambdas。它们可以引用在封闭范围内命名的对象,但只能引用 finals,因此它们不能改变任何东西(与 C# 中的 lambdas 不同)。

    此外,非常冗长的语法也是一种痛苦。人们经常建议 Java 应该为只有一个抽象(或接口)方法的情况提供更简单的语法,因此不需要为您想要覆盖的内容提供名称或类型声明。然后是没有类型推断的事实,也没有明显的方法在泛型类构造函数上提供它,因为new Select(filtered) 已经意味着其他东西。

    SelectWhere 的实现是:

    abstract class Select<TSource, TResult> implements Iterable<TResult>
    {
        private Iterable<TSource> _source;
    
        public Select(Iterable<TSource> source)
            { _source = source; }
    
        private class Iter implements Iterator<TResult>
        {
            private Iterator<TSource> _i;
    
            public Iter() { _i = _source.iterator(); }
    
            public void remove()
                { _i.remove(); }
    
            public boolean hasNext()
                { return _i.hasNext(); }
    
            public TResult next()
                { return select(_i.next()); }
        }
    
        protected abstract TResult select(TSource source);
    
        public Iterator<TResult> iterator()
            { return new Iter(); }
    }
    
    abstract class Where<TSource> implements Iterable<TSource>
    {
        private Iterable<TSource> _source;
    
        public Where(Iterable<TSource> source)
            { _source = source; }
    
        private class Iter implements Iterator<TSource>
        {
            private Iterator<TSource> _i;
            private TSource _cachedNext;
            private boolean _hasCachedNext;
    
            public Iter()
            {
                _i = _source.iterator();
                fetch();
            }
    
            public void remove()
                { _i.remove(); }
    
            public boolean hasNext()
                { return _hasCachedNext; }
    
            public TSource next()
            {
                TSource result = _cachedNext;
                fetch();
                return result;
            }
    
            private void fetch()
            {
                _hasCachedNext = false;
    
                while (_i.hasNext())
                {
                    _cachedNext = _i.next();
                    if (predicate(_cachedNext))
                    {
                        _hasCachedNext = true;
                        return;
                    }
                }
            }
        }
    
        protected abstract boolean predicate(TSource source);
    
        public Iterator<TSource> iterator()
            { return new Iter(); }
    }
    

    【讨论】:

      【解决方案4】:

      SBQL4J 可以满足您的要求。它是 Java 语言的类型安全扩展,但它也 100% 兼容 Java 6 VM。 SBQL4J 提供类似于 LINQ-to-objects 的功能。

      Daniel 的查询示例应该是这样的:

      Vector<Integer> numbers = new Vector<Integer>();
      
      numbers.add(42);
      numbers.add(3);
      numbers.add(16);
      numbers.add(92);
      numbers.add(9);
      
      Iterable<Integer> filtered = #{ numbers as n where n > 10 };
      
      Iterable<String> converted = #{ numbers.toString() };
      
      for (final String str : converted)
          System.out.println(str);
      

      查询语言大约有35个运算符,包括选择、投影、排序、算术运算符、聚合、传递闭包、范围等。

      【讨论】:

        【解决方案5】:

        extra166y addendum to JSR166y 带有 ParallelArray 构造。基本上是对象数组的 PLINQ。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-03
          • 1970-01-01
          • 1970-01-01
          • 2010-11-05
          • 1970-01-01
          相关资源
          最近更新 更多