2009-07-08 8 views
5

私は元々.NET Javaの人で、Javaで最近働いていて、特にコレクションに対するフィルタリングを実行するために、LINQがObjectに本当に欠けていることがわかりました。クアエール - 誰でもまだ使っていますか? (LINQ to Objects for Java)

Stack Overflowでここ数人が「LINQ for Java?」と答えました。単一の単語との質問には:

Quaere

ただし、サイト上でそれは明らかに「プリベータ版」を述べ、及び年以上のために自分のコードへのコミットが行われていないですので、私はよプロジェクトを推測することはかなり致命的です。

これを実際に使用している人はいますか?

2番目によくある回答は「Googleコレクションを使用する」と思われます。これは最も適切なJavaの方法ですか?オブジェクトへの簡単なLINQのために

乾杯

マーティ

+1

オブジェクトへのlinqについては、github.com/nicholas22/jpropel-lightをチェックしてください。実際の例:new String [] {"james"、 "john"、 "john"、 "eddie"} .where(startsWith( "j")) .toList()。distinct(); –

答えて

5

あなたはQuaereはJavaでLINQを持つパイオニアの位置にあるのではなく、lambdajライブラリを使用して、より読みやすい形で

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

+0

+1リンクのおかげで非常にいいですね。 – skaffman

+0

質問を投稿してからしばらくlambajを使っていましたが(更新は忘れました) 本当に素晴らしいプロジェクトです。 –

+1

私は個人的にはLINQの誇大宣伝をまったく理解していません。特にLambdaJが何をしているのか見た後では、それはどうですか? +1の価値があります。 – Esko

1

、私は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); 

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

また、非常に冗長な構文は痛みです。人々はしばしば、抽象(またはインタフェース)メソッドが1つしかない場合にJavaがより単純な構文を提供する必要があることを提案しています。したがって、オーバーライドする名前または型宣言を与える必要はありません。 new Select(filtered)は型の推論がないという事実があります。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(); } 
} 
3

をコレクション内の項目を選択します(とはるかに)することができますtypesafeは、LINQの主なポイントの1つです。

Querydslはタイプセーフで、コレクションのフィルタリング、並べ替え、投影をサポートしています。

JPA/Hibernate、JDO、SQLバックエンドに対する操作もサポートしています。

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

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

1

SBQL4Jは、お客様の要件を満たす場合があります。 Java言語に対する型安全拡張ですが、Java 6 VMと100%互換性もあります。 SBQL4Jは、LINQからオブジェクトへの類似の機能を提供します。

ダニエルのクエリの例は次のようにすべきである:

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オペレータ、等

があります
関連する問題