對於簡單的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);
請注意,我還沒有得到Where
和Select
鏈接在一起表達。我可以將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(); }
}
對於linq到對象檢查github.com/nicholas22/jpropel-light,真實的例子:new String [] {「james」,「john」,「john」,「eddie」} .where(startsWith(「j」)) .toList()不同(); – 2011-10-08 10:21:50