5

私はもともと .NET の人間で、最近 Java で作業していて、LINQ to Objects、特にコレクションに対してフィルタリングを実行する機能が本当に不足していることに気付きました。

Stack Overflow の何人かが、「LINQ for Java?」に答えています。一言で質問 :

クエーレ

しかし、サイトでは「Pre-Beta」と明確に記載されており、1 年以上コードにコミットされていないため、プロジェクトはほとんど死んでいると思います。

誰かが実際にこれを使用していますか、および/または経験がありますか?

2 番目に多い回答は、「Google コレクションを使用する」のようです。これは最も適切な Java の方法ですか?

乾杯

マーティ

4

5 に答える 5

5

lambdaj ライブラリを使用すると、より読みやすい方法でコレクション内のアイテム (およびその他のアイテム) を選択できます。

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

于 2009-09-12T07:55:33.843 に答える
3

Quaere は Java での LINQ のパイオニア的立場にありますが、LINQ の主なポイントの 1 つであるタイプセーフではありません。

Querydslはタイプ セーフであり、コレクションのフィルタリング、並べ替え、および射影をサポートします。

JPA/Hibernate、JDO、および SQL バックエンドでの操作もサポートしています。

構文は SQL に似ていますが、基本的な順序が from-where-list であるという違いがあります。

私は Querydsl のメンテナーなので、この回答は偏っています。

于 2010-01-11T20:30:38.057 に答える
1

SBQL4Jはあなたの要求を満たすかもしれません。これは Java 言語のタイプ セーフな拡張機能ですが、Java 6 VM と 100% 互換性があります。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 に答える
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);

1 つの式で連結しWhereていないことに注意してください。Selectの定義をfilteredそれが使用されている 1 つの場所に挿入することもできますが、それではおそらく (さらに) 読みにくくなります。問題は、拡張メソッドとラムダがないことです。ラムダに最も近いのは、これらの匿名クラス宣言によるものです。それらは、囲んでいるスコープで名前が付けられたオブジェクトを参照できますが、finals のみであるため、何も変更できません (C# のラムダとは異なります)。

また、非常に冗長な構文も苦痛です。抽象 (またはインターフェース) メソッドが 1 つしかない場合、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 に答える
0

ParallelArrayコンストラクトを持つJSR166yには、extra166y の補遺があります。基本的に、オブジェクト配列の PLINQ です。

于 2009-07-17T16:58:05.350 に答える