对于简单的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