2009-07-08 9 views
5

Ich bin ursprünglich ein .NET-Typ, der vor kurzem in Java gearbeitet hat und festgestellt hat, dass ich LINQ to Objects wirklich vermisse, speziell für die Filterung gegen Sammlungen.Quaere - Wer benutzt es schon? (LINQ to Objects für Java)

Ein paar Leute hier auf Stack Overflow haben die "LINQ for Java?" Frage mit einem einzigen Wort:

Quaere

jedoch auf der Website heißt es eindeutig „Pre-Beta“, und es ist seit über einem Jahr keine Festschreibungen zu ihren Code gewesen, also bin ich Das Projekt zu schätzen, ist ziemlich tot.

Hat jemand das tatsächlich benutzt und/oder irgendwelche Erfahrungen damit?

Die zweithäufigste Antwort scheint "Google Collections verwenden" zu sein. Ist das der geeignetste Java-Weg?

Prost

Marty

+1

Für Linq Objekte überprüfen github.com/nicholas22/jpropel-light, reales Beispiel: new String [] {"James", "John", "John", "Eddie"} .where (startsWith ("j")) .toList(). distinct(); –

Antwort

5

Sie können die Elemente in einer Sammlung auswählen (und vieles mehr) in einer besser lesbaren Art und Weise durch die lambdaj Bibliothek

http://code.google.com/p/lambdaj/

+0

+1 Sieht sehr nett aus, danke für den Link. – skaffman

+0

Ja, ich benutze Lambda seit der Veröffentlichung der Frage eine Weile (aber vergessen zu aktualisieren.) Danke für den Link - es ist wirklich ein großartiges Projekt. –

+1

Ich persönlich verstehe den Hype um LINQ überhaupt nicht, besonders nachdem ich gesehen habe, was LambdaJ macht (und wie!). Definitiv eine +1 wert. – Esko

1

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(); } 
} 
3

Quaere ist in einer Pionier-Position mit LINQ in Java, ist aber nicht typsicher, was einer der Hauptpunkte von LINQ ist.

Querydsl ist typsicher und unterstützt das Filtern, Sortieren und Projizieren von Sammlungen.

Es unterstützt auch Operationen auf JPA/Hibernate, JDO und SQL-Backends.

Die Syntax ähnelt SQL mit dem Unterschied, dass die grundlegende Reihenfolge von wo-Liste ist.

Ich bin der Betreuer von Querydsl, also ist diese Antwort voreingenommen.

1

SBQL4J können erfüllen Ihre Anforderungen. Es ist eine sichere Erweiterung der Java-Sprache, aber es ist auch 100% kompatibel mit Java 6 VM. SBQL4J bietet ähnliche Funktionen wie LINQ-to-objects.

sollte Daniels Abfrage Beispiele wie dieses:

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); 

Es gibt etwa 35 Operatoren der Abfragesprache, einschließlich der Auswahl, Projektion, Bestellung, arithmetische Operatoren, Aggregation, transitive Schließung, Reichweite usw.