、私は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)
は既に何かを意味するので、ジェネリッククラスのコンストラクタにそれを提供する明白な方法はありません。
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()。distinct(); –