Was ist Java-Äquivalent für LINQ?
Was ist Java-Äquivalent für LINQ?
Antworten:
Es gibt nichts Schöneres als LINQ für Java.
...
Bearbeiten
Mit Java 8 werden wir nun in die Stream-API eingeführt . Dies ist ähnlich, wenn es um Sammlungen geht, aber es ist nicht ganz dasselbe wie bei Linq.
Wenn es sich um ein ORM handelt, nach dem Sie suchen, wie z. B. Entity Framework, können Sie den Ruhezustand ausprobieren
:-)
Es gibt eine alternative Lösung, Coollection .
Coolection hat nicht vorgetäuscht, das neue Lambda zu sein, aber wir sind von alten Java-Legacy-Projekten umgeben, bei denen diese Bibliothek helfen wird. Es ist wirklich einfach zu verwenden und zu erweitern und deckt nur die am häufigsten verwendeten Iterationsaktionen über Sammlungen ab:
from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();
Lambdas sind jetzt in Java 8 in Form von JSR-335 - Lambda Expressions für die JavaTM-Programmiersprache verfügbar
UPDATE : JDK8 wurde jetzt veröffentlicht, das das Projekt Lambda enthält. Es lohnt sich, eine Kopie von Java 8 in Aktion zu erwerben, die derzeit noch MEAP ist.
Lesen Sie die Artikel von Brian Goetz zu Lambdas, um ein gutes Verständnis für die Implementierung von Lambdas in JDK8 zu erhalten, und lernen Sie gleichzeitig Streams, interne Iterationen, Kurzschlüsse und Konstruktorreferenzen kennen. Weitere Beispiele finden Sie in den obigen JSRs .
Ich habe einen Blog über einige der Vorteile der Verwendung von Lambdas in JDK8 mit dem Namen The Power of the Arrow geschrieben . NetBeans 8 bietet auch hervorragende Unterstützung für die Konvertierung von Konstrukten in JDK8, über die ich auch über die Migration auf JDK 8 mit NetBeans gebloggt habe .
Mithilfe der Lambdaj-Bibliothek können Sie die Elemente in einer Sammlung (und vieles mehr) besser lesbar auswählen
https://code.google.com/archive/p/lambdaj/
Es hat einige Vorteile gegenüber der Quaere-Bibliothek, da es keine magische Zeichenfolge verwendet, absolut typsicher ist und meiner Meinung nach ein besser lesbares DSL bietet.
Sie werden kein Äquivalent zu LINQ finden, es sei denn, Sie verwenden den Javacc , um Ihr eigenes Äquivalent zu erstellen.
Bis zu dem Tag, an dem jemand einen praktikablen Weg findet, gibt es einige gute Alternativen, wie z
LINQ to Objects - JAVA 8 hat die Stream-API hinzugefügt, die Unterstützung für Operationen im funktionalen Stil für Werteströme bietet:
Java 8 erklärt: Anwenden von Lambdas auf Java-Sammlungen
LINQ zu SQL / NHibernate / etc. (Datenbankabfrage) - Eine Option wäre die Verwendung von JINQ, das auch die neuen JAVA 8-Funktionen verwendet und am 26. Februar 2014 auf Github veröffentlicht wurde: https://github.com/my2iu/Jinq
Jinq bietet Entwicklern eine einfache und natürliche Möglichkeit, Datenbankabfragen in Java zu schreiben. Sie können Datenbankdaten wie normale Java-Objekte behandeln, die in Sammlungen gespeichert sind. Sie können sie durchlaufen und mit normalen Java-Befehlen filtern. Der gesamte Code wird automatisch in optimierte Datenbankabfragen übersetzt. Schließlich sind Abfragen im LINQ-Stil für Java verfügbar!
JINQ-Projektseite: http://www.jinq.org/
Es gibt ein Projekt namens quaere .
Es ist ein Java-Framework, das die Möglichkeit bietet, Sammlungen abzufragen.
Hinweis: Laut Autor wird das Projekt nicht mehr gepflegt.
from x in xs select x
und die Antwort herausfinden können (nein).
Es gibt viele LINQ-Entsprechungen für Java, siehe hier für einen Vergleich.
Erwägen Sie für ein typsicheres Quaere / LINQ-Framework die Verwendung von Querydsl . Querydsl unterstützt JPA / Hibernate-, JDO-, SQL- und Java-Sammlungen.
Ich bin der Betreuer von Querydsl, daher ist diese Antwort voreingenommen.
Wie im Jahr 2014 kann ich endlich sagen, dass LINQ endlich in Java 8 verfügbar ist. Sie müssen also keine Alternative mehr zu LINQ finden.
Jetzt, da Java 8 Lambdas unterstützt, ist es möglich, Java-APIs zu erstellen, die LINQ sehr ähnlich sind.
Jinq ist eine dieser neuen LINQ-Bibliotheken für Java.
Ich bin der Entwickler dieser Bibliothek. Es basiert auf fünf Jahren Forschung zur Verwendung der Bytecode-Analyse zur Übersetzung von Java in Datenbankabfragen. Ähnlich wie C # D-LINQ eine Abfrageebene ist, die über dem Entity Framework liegt, kann Jinq als Abfrageebene über JPA oder jOOQ fungieren. Es unterstützt Aggregation, Gruppen und Unterabfragen. Sogar Erik Meijer (der Schöpfer von LINQ) hat Jinq anerkannt .
Siehe SBQL4J . Es ist eine typsichere, starke Abfragesprache, die in Java integriert ist. Ermöglicht das Schreiben komplizierter und mehrfach verschachtelter Abfragen. Es gibt viele Operatoren, Java-Methoden können als Konstruktoren in Abfragen aufgerufen werden. Abfragen werden in reinen Java-Code übersetzt (zur Laufzeit gibt es keine Reflexion), sodass die Ausführung sehr schnell erfolgt.
EDIT: Nun, bis jetzt ist SBQL4J die EINZIGE Erweiterung der Java-Sprache, die ähnliche Abfragefunktionen wie LINQ bietet. Es gibt einige interessante Projekte wie Quaere und JaQue, aber es handelt sich nur um APIs, nicht um Syntax- / Semantik-Erweiterungen mit hoher Typensicherheit in der Kompilierungszeit.
Java LINQ to SQL- Implementierung. Bietet vollständige Sprachintegration und größere Funktionen im Vergleich zu .NET LINQ.
Ich habe Guavenbibliotheken von Google ausprobiert . Es hat eine, von FluentIterable
der ich denke, dass sie LINQ nahe kommt. Siehe auch FunctionalExplained .
List<String> parts = new ArrayList<String>(); // add parts to the collection.
FluentIterable<Integer> partsStartingA =
FluentIterable.from(parts).filter(new Predicate<String>() {
@Override
public boolean apply(final String input) {
return input.startsWith("a");
}
}).transform(new Function<String, Integer>() {
@Override
public Integer apply(final String input) {
return input.length();
}
});
Scheint eine umfangreiche Bibliothek für Java zu sein. Sicher nicht so prägnant wie LINQ, sieht aber interessant aus.
https://code.google.com/p/joquery/
Unterstützt verschiedene Möglichkeiten,
Gegebene Sammlung,
Collection<Dto> testList = new ArrayList<>();
vom Typ,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Filter
Java 7
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property("id").eq().value(1);
Collection<Dto> filtered = query.list();
Java 8
Filter<Dto> query = CQ.<Dto>filter(testList)
.where()
.property(Dto::getId)
.eq().value(1);
Collection<Dto> filtered = query.list();
Ebenfalls,
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.property(Dto::getId).between().value(1).value(2)
.and()
.property(Dto::grtText).in().value(new string[]{"a","b"});
Sortieren (auch für Java 7 verfügbar)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Gruppierung (auch für Java 7 verfügbar)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Joins (auch für Java 7 verfügbar)
Gegeben,
class LeftDto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
class RightDto
{
private int id;
private int leftId;
private String text;
public int getId()
{
return id;
}
public int getLeftId()
{
return leftId;
}
public int getText()
{
return text;
}
}
class JoinedDto
{
private int leftId;
private int rightId;
private String text;
public JoinedDto(int leftId,int rightId,String text)
{
this.leftId = leftId;
this.rightId = rightId;
this.text = text;
}
public int getLeftId()
{
return leftId;
}
public int getRightId()
{
return rightId;
}
public int getText()
{
return text;
}
}
Collection<LeftDto> leftList = new ArrayList<>();
Collection<RightDto> rightList = new ArrayList<>();
Kann verbunden werden wie,
Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
.<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
.on(LeftFyo::getId, RightDto::getLeftId)
.transformDirect(selection -> new JoinedDto(selection.getLeft().getText()
, selection.getLeft().getId()
, selection.getRight().getId())
)
.list();
Ausdrücke
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
Sie können meine Bibliothek CollectionsQuery ausprobieren . Es ermöglicht die Ausführung von LINQ-ähnlichen Abfragen über Sammlungen von Objekten. Sie müssen ein Prädikat übergeben, genau wie in LINQ. Wenn Sie Java6 / 7 verwenden, müssen Sie die alte Syntax für Schnittstellen verwenden:
List<String> names = Queryable.from(people)
.filter(new Predicate<Person>() {
public boolean filter(Person p) {
return p.age>20;
}
})
.map (new Converter<Person,String>() {
public Integer convert(Person p) {
return p.name;
}
})
.toList();
Sie können es auch in Java8 oder in altem Java mit RetroLambda und dem Gradle-Plugin verwenden , dann haben Sie eine neue ausgefallene Syntax:
List<String> names = Queryable.from(people)
.filter(p->p.age>20)
.map (p->p.name)
.toList();
Wenn Sie DB-Abfragen ausführen müssen, können Sie, wie oben erwähnt, auf JINQ schauen, es kann jedoch nicht von RetroLambda zurückportiert werden, um serialisierte Lambdas zu verwenden.
Nur um eine weitere Alternative hinzuzufügen: Java 6 bietet eine Lösung für typsichere Datenbankabfragen mit dem Paket javax.persistence.criteria .
Obwohl ich sagen muss, dass dies nicht wirklich LINQ ist, weil Sie mit LINQ jede IEnumerable abfragen können.
Es gibt eine sehr gute Bibliothek, die Sie dafür verwenden können.
Befindet sich hier: https://github.com/nicholas22/jpropel-light
Lambdas werden jedoch erst in Java 8 verfügbar sein, daher ist die Verwendung etwas anders und fühlt sich nicht so natürlich an.
Es klingt so, als wäre der Linq, von dem hier alle sprechen, nur LinqToObjects. Was meiner Meinung nach nur Funktionen bietet, die bereits heute in Java ausgeführt werden können, aber mit wirklich hässlicher Syntax.
Was ich als die wahre Stärke von Linq in .Net sehe, ist, dass Lambda-Ausdrücke in einem Kontext verwendet werden können, der entweder einen Delegaten oder einen Ausdruck erfordert, und dann in die entsprechende Form kompiliert werden. Auf diese Weise können Dinge wie LinqToSql (oder etwas anderes als LinqToObjects) funktionieren und eine Syntax haben, die mit LinqToObjects identisch ist.
Es sieht so aus, als ob alle oben genannten Projekte nur die Funktionen von LinqToObjects bieten. Aus diesem Grund ist die Funktionalität vom Typ LinqToSql für Java nicht in Sicht.
Für grundlegende Funktionssammlungen ist Java 8 integriert, die meisten wichtigen Nicht-Java-JVM-Sprachen (Scala, Clojure usw.) und Sie können zusätzliche Bibliotheken für frühere Java-Versionen erhalten.
Für den vollsprachigen integrierten Zugriff auf eine SQL-Datenbank verfügt Scala (läuft auf der JVM) über Slick
Für LINQ (LINQ to Objects) hat Java 8 etwas Äquivalentes, siehe Project Lambda .
Es hat Enumerables LINQ to Objects-Erweiterungen wie Stuff . Aber für kompliziertere LINQ-Dinge wie Expression und ExpressionTree (diese werden für LINQ to SQL und andere LINQ-Anbieter benötigt, wenn sie etwas Optimiertes und Reales bereitstellen möchten) gibt es noch kein Äquivalent, aber vielleicht werden wir das in Zukunft sehen :)
Aber ich glaube nicht, dass es in Zukunft so etwas wie deklarative Abfragen unter Java geben wird.
In Java gibt es keine solche Funktion. Wenn Sie die andere API verwenden, erhalten Sie diese Funktion. Nehmen wir an, wir haben ein Tierobjekt, das Name und ID enthält. Wir haben Listenobjekte mit Tierobjekten. Wenn wir nun den gesamten Tiernamen, der 'o' enthält, vom Listenobjekt erhalten möchten. Wir können die folgende Abfrage schreiben
from(animals).where("getName", contains("o")).all();
Die obige Abfrageanweisung listet die Tiere auf, deren Name das 'o'-Alphabet enthält. Weitere Informationen finden Sie im folgenden Blog. http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
Schauen Sie sich tiny-q an . (Beachten Sie, dass Sie es derzeit nicht herunterladen können.)
Hier ist ein Beispiel, das den obigen Link angepasst hat:
Zuerst benötigen wir eine Sammlung einiger Daten, sagen wir eine Reihe von Zeichenfolgen
String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };
Jetzt wollen wir nur die Strings auswählen, die mit "b" beginnen:
Query<String> stringsStartingWithB = new Query<String>(strings).where(
new Query.Func<String, Boolean>(){
public Boolean run(String in) {
return in.startsWith("b");
}
}
);
Keine tatsächlich verschobenen Daten kopiert oder ähnliches, sie werden verarbeitet, sobald Sie mit der Iteration beginnen:
for(String string : stringsStartingWithB ) {
System.out.println(string);
}
JaQu ist das LINQ-Äquivalent für Java. Obwohl es für die H2-Datenbank entwickelt wurde, sollte es für jede Datenbank funktionieren, da es JDBC verwendet.
Vielleicht nicht die Antwort, auf die Sie hoffen, aber wenn ein Teil Ihres Codes umfangreiche Arbeiten an Sammlungen (Suchen, Sortieren, Filtern, Transformationen, Analysen) erfordert, können Sie in Betracht ziehen, einige Klassen in Clojure oder Scala zu schreiben .
Aufgrund ihrer funktionalen Natur ist die Arbeit mit Kollektionen das, was sie am besten können. Ich habe nicht viel Erfahrung mit Scala, aber mit Clojure finden Sie wahrscheinlich einen leistungsstärkeren Linq an Ihren Fingerspitzen. Nach dem Kompilieren lassen sich die von Ihnen erstellten Klassen nahtlos in den Rest der Codebasis integrieren.
Ein anonymer Benutzer erwähnte einen anderen, Diting :
Diting ist eine Klassenbibliothek, die Abfragefunktionen für Sammlungen über verkettbare Methoden und eine anonyme Schnittstelle wie Linq in .NET bereitstellt. Im Gegensatz zu den meisten anderen Sammlungsbibliotheken, die statische Methoden verwenden, muss die gesamte Sammlung iteriert werden. Diting bietet einen Kern der Enumerable-Klasse, der verzögerte verkettbare Methoden zum Implementieren von Abfragen für Sammlungen oder Arrays enthält.
Unterstützte Methoden: any, cast, contact, enthält, count, unique, elementAt, außer first, firstOrDefault, groupBy, interset, join, last, lastOrDefault, ofType, orderBy, orderByDescending, reverse, select, selectMany, single, singleOrDefault, skip , skipWhile, take, takeWhile, toArray, toArrayList, union, where
Scala. Jetzt lese ich es und fand es wie linq, aber einfacher und unleserlicher. aber scala kann unter linux laufen, ja? csharp brauchen mono.
Es gab die Programmiersprache Pizza (eine Java-Erweiterung) und Sie sollten einen Blick darauf werfen. - Es verwendet das Konzept der "fließenden Schnittstellen", um Daten deklarativ abzufragen. Dies ist im Prinzip identisch mit LINQ ohne Abfrageausdrücke (http://en.wikipedia.org/wiki/Pizza_programming_language). Aber leider wurde es nicht weiterverfolgt, aber es wäre eine Möglichkeit gewesen, etwas Ähnliches wie LINQ in Java zu bringen.
Es gibt kein Äquivalent zu LINQ für Java. Es gibt jedoch einige externe APIs, die wie LINQ aussehen, z. B. https://github.com/nicholas22/jpropel-light , https://code.google.com/p/jaque/
Sie können diese Bibliothek ausprobieren: https://code.google.com/p/qood/
Hier sind einige Gründe, es zu verwenden: