Für einfache Linq Um Objekte, die beste, die ich denken kann in Java ist so etwas geschehen:
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);
Bitte beachte, dass ich nicht Where
bekommen haben und Select
Verkettung in einem Ausdruck. Ich könnte die Definition von filtered
in den einen Platz einfügen, den es benutzt, aber das würde es wahrscheinlich (sogar) weniger lesbar machen. Die Probleme sind das Fehlen von Erweiterungsmethoden und Lambdas. Am ehesten erreichen wir Lambdas mit diesen anonymen Klassendeklarationen. Sie können auf Objekte verweisen, die im einschließenden Bereich angegeben sind, aber nur final
s, so dass sie nichts mutieren können (anders als Lambdas in C#).
Auch die sehr ausführliche Syntax ist ein Schmerz. Die Leute haben oft vorgeschlagen, dass Java eine einfachere Syntax für Fälle bieten sollte, in denen es nur eine abstrakte (oder Interface-) Methode gibt, und daher gibt es keine Notwendigkeit, den Namen oder die Typdeklarationen für das zu geben, was Sie überschreiben möchten. Dann gibt es die Tatsache, dass es keine Typ-Inferenz gibt, und keine offensichtliche Möglichkeit, sie auf generischen Klassenkonstruktoren bereitzustellen, weil new Select(filtered)
bereits etwas anderes bedeutet.
Die Implementierungen für Select
und Where
sind:
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(); }
}
Für Linq Objekte überprüfen github.com/nicholas22/jpropel-light, reales Beispiel: new String [] {"James", "John", "John", "Eddie"} .where (startsWith ("j")) .toList(). distinct(); –