5

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

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

夸尔

然而,在网站上它清楚地表明“Pre-Beta”,并且一年多来没有提交他们的代码,所以我猜这个项目几乎已经死了。

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

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

干杯

马蒂

4

5 回答 5

5

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

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

于 2009-09-12T07:55:33.843 回答
3

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

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

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

语法与 SQL 类似,区别在于基本顺序是 from-where-list。

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

于 2010-01-11T20:30:38.057 回答
1

对于简单的 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链接在一起。我可以将 of 的定义插入filtered它使用的一个地方,但这可能会使其(甚至)不那么可读。问题是缺少扩展方法和 lambdas。我们可以通过这些匿名类声明最接近 lambdas。它们可以引用在封闭范围内命名的对象,但只能引用finals,因此它们不能改变任何东西(与 C# 中的 lambdas 不同)。

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

Select和的实现Where是:

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(); }
}
于 2009-07-17T16:47:56.260 回答
1

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

丹尼尔的查询示例应该是这样的:

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 个运算符,包括选择、投影、排序、算术运算符、聚合、传递闭包、范围等。

于 2010-08-07T06:04:25.550 回答
0

JSR166y有额外的166y 附录,带有ParallelArray构造。基本上是对象数组的 PLINQ。

于 2009-07-17T16:58:05.350 回答