2009-07-08 75 views
5

我最初是一名.NET人,最近在Java工作,發現我確實缺少LINQ to Objects,專門針對集合執行過濾。Quaere - 任何人使用它? (LINQ to Objects)

Stack Overflow上的一些人已經回答了「LINQ for Java?」一個字的問題:

Quaere

然而,在網站上也明確指出「預測試版」,而且也一直沒有提交給他們的代碼一年多了,所以我猜測該項目已經死了。

是否有人真的使用過它,和/或有任何經驗?

第二個最常見的答案似乎是「使用Google Collections」。這是最合適的Java方式嗎?

乾杯

馬蒂

+1

對於linq到對象檢查github.com/nicholas22/jpropel-light,真實的例子:new String [] {「james」,「john」,「john」,「eddie」} .where(startsWith(「j」)) .toList()不同(); – 2011-10-08 10:21:50

回答

5

您可以通過使用lambdaj庫

http://code.google.com/p/lambdaj/選擇更可讀的方式集合中的項目(以及更多)

+0

+1看起來非常好,謝謝你的鏈接。 – skaffman 2009-09-12 08:03:09

1

對於簡單的LINQ到對象,我認爲最好的可以用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的定義插入到其使用的位置,但這可能會使其(甚至)更不可讀。問題是缺乏擴展方法和lambda。我們可以最接近lambdas的是這些匿名類聲明。它們可以引用在封閉範圍內命名的對象,但只能使用final s,所以它們不能改變任何東西(與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(); } 
} 
3

Quaere與LINQ在Java中的先鋒地位,但不類型安全,這是LINQ的一個要點。

Querydsl是類型安全,並支持過濾,排序和突出類別。

它支持對JPA/Hibernate,JDO和SQL後端的操作。

語法與SQL類似,不同之處在於基本順序來自where-list。

我是Querydsl的維護者,所以這個答案是有偏見的。

1

SBQL4J可能會滿足您的要求。它是Java語言的類型安全擴展,但它也與Java 6 VM完全兼容。 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運營商的查詢語言,包括選擇,投影,排序,算術運算符,聚集,傳遞閉包,範圍等