Co to jest odpowiednik Java dla LINQ?
Co to jest odpowiednik Java dla LINQ?
Odpowiedzi:
Nie ma nic takiego jak LINQ dla Java.
...
Edytować
Teraz, gdy w Javie 8 wprowadzono nas do Stream Stream , jest to podobna sprawa w przypadku kolekcji, ale nie jest to dokładnie to samo, co Linq.
Jeśli szukasz ORM, takiego jak Entity Framework, możesz wypróbować Hibernację
:-)
Istnieje alternatywne rozwiązanie, Coollection .
Coolection nie udaje, że jest nową lambda, jednak jesteśmy otoczeni starymi starszymi projektami Java, w których ta biblioteka pomoże. Jest naprawdę prosty w użyciu i rozszerzany, obejmując tylko najczęściej używane akcje iteracji nad kolekcjami, takie jak:
from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();
Lambdas są teraz dostępne w Javie 8 w postaci JSR-335 - wyrażenia lambda dla języka programowania JavaTM
AKTUALIZACJA : JDK8 został wydany i zawiera projekt lambda. Warto pobrać kopię Java 8 w akcji, która wciąż jest MEAP.
Zapoznaj się z artykułami Briana Goetza dotyczącymi lambd, aby dobrze zrozumieć, w jaki sposób lambd są implementowane w JDK8, a także zrozumieć strumienie, wewnętrzną iterację, zwarcie i odniesienia do konstruktorów. Sprawdź także JSR powyżej, aby uzyskać dalsze przykłady .
Napisałem bloga o niektórych zaletach używania lambd w JDK8 o nazwie The Power of the Arrow , również NetBeans 8 ma świetne wsparcie dla konwersji konstruktów do JDK8, o którym również pisałem na blogu o migracji do JDK 8 za pomocą NetBeans .
Możesz wybierać elementy z kolekcji (i wiele więcej) w bardziej czytelny sposób, korzystając z biblioteki lambdaj
https://code.google.com/archive/p/lambdaj/
Ma pewne zalety w stosunku do biblioteki Quaere, ponieważ nie używa żadnego magicznego ciągu, jest całkowicie bezpieczny dla typów i moim zdaniem oferuje bardziej czytelny DSL.
Nie znajdziesz odpowiednika LINQ, chyba że użyjesz javacc do stworzenia własnego odpowiednika.
Do tego dnia, gdy ktoś znajdzie realny sposób, istnieje kilka dobrych alternatyw, takich jak
LINQ do Objects - JAVA 8 dodał API Stream, który dodaje obsługę funkcjonalnych operacji na strumieniach wartości:
Wyjaśnienie Java 8: Stosowanie Lambdas do kolekcji Java
LINQ do SQL / NHibernate / itp. (zapytania do bazy danych) - Jedną z opcji byłoby użycie JINQ, który również korzysta z nowych funkcji JAVA 8 i został wydany 26 lutego 2014 roku na Github: https://github.com/my2iu/Jinq
Jinq zapewnia programistom łatwy i naturalny sposób pisania zapytań do baz danych w Javie. Dane bazy danych można traktować jak normalne obiekty Java przechowywane w kolekcjach. Możesz iterować nad nimi i filtrować je przy użyciu normalnych poleceń Java, a cały kod zostanie automatycznie przetłumaczony na zoptymalizowane zapytania do bazy danych. Wreszcie, zapytania w stylu LINQ są dostępne dla Java!
Strona projektu JINQ: http://www.jinq.org/
Istnieje projekt o nazwie quaere .
Jest to framework Java, który dodaje możliwość zapytania do kolekcji.
Uwaga: Według autora projekt nie jest już utrzymywany.
from x in xs select x
i znaleźć odpowiedź (nie).
Istnieje wiele odpowiedników LINQ dla Java, zobacz tutaj dla porównania.
W przypadku bezpiecznej dla stylu struktury Quaere / LINQ rozważ użycie Querydsl . Querydsl obsługuje kolekcje JPA / Hibernate, JDO, SQL i Java.
Jestem opiekunem Querydsl, więc ta odpowiedź jest stronnicza.
Podobnie jak w 2014 roku, mogę wreszcie powiedzieć, że LINQ jest już dostępny w Javie 8, więc nie muszę już szukać alternatywy dla LINQ.
Teraz, gdy Java 8 obsługuje lambdy, możliwe jest tworzenie interfejsów API Java, które bardzo przypominają LINQ.
Jinq jest jedną z tych nowych bibliotek w stylu LINQ dla Java.
Jestem programistą tej biblioteki. Opiera się na pięciu latach badań nad wykorzystaniem analizy kodu bajtowego do tłumaczenia zapytań Java na bazy danych. Podobnie jak D-LINQ w C # jest warstwą zapytania, która znajduje się na frameworku Entity Framework, Jinq może działać jako warstwa zapytania oparta na JPA lub jOOQ. Obsługuje agregację, grupy i podkwerendy. Nawet Erik Meijer (twórca LINQ) uznał Jinq .
Zobacz SBQL4J . Jest to silny język zapytań bezpieczny dla typu zintegrowany z Javą. Pozwala pisać skomplikowane i wielokrotnie zagnieżdżone zapytania. Istnieje wiele operatorów, metody Java mogą być wywoływane wewnątrz zapytań, takich jak konstruktory. Zapytania są tłumaczone na czysty kod Java (nie ma refleksji w czasie wykonywania), więc wykonanie jest bardzo szybkie.
EDYCJA: Cóż, jak dotąd SBQL4J jest JEDYNYM rozszerzeniem języka Java, które daje możliwości zapytania podobne do LINQ. Istnieje kilka interesujących projektów, takich jak Quaere i JaQue, ale są one tylko interfejsem API, a nie rozszerzeniem składni / semantyki z silnym bezpieczeństwem typów w czasie kompilacji.
Implementacja Java LINQ do SQL . Zapewnia pełną integrację językową i większy zestaw funkcji w porównaniu do .NET LINQ.
Próbowałem bibliotek guava z google. Ma taki, FluentIterable
który moim zdaniem jest zbliżony do LINQ. Zobacz także 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();
}
});
Wydaje się być obszerną biblioteką dla Java. Z pewnością nie tak zwięzły jak LINQ, ale wygląda interesująco.
https://code.google.com/p/joquery/
Obsługuje różne możliwości,
Biorąc pod uwagę kolekcję,
Collection<Dto> testList = new ArrayList<>();
typu
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Filtr
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();
Również,
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"});
Sortowanie (dostępne również dla Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Grupowanie (dostępne również dla Java 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Połączenia (dostępne również dla Java 7)
Dany,
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<>();
Można dołączyć,
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();
Wyrażenia
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
Możesz wypróbować moją bibliotekę CollectionsQuery . Pozwala na uruchamianie zapytań LINQ na kolekcje obiektów. Musisz przekazać predykat, tak jak w LINQ. Jeśli używasz java6 / 7, musisz użyć starej składni z interfejsami:
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();
Możesz także użyć go w Javie 8 lub w starej Javie z RetroLambda i wtyczką gradle , wtedy będziesz mieć nową fantazyjną składnię:
List<String> names = Queryable.from(people)
.filter(p->p.age>20)
.map (p->p.name)
.toList();
Jeśli potrzebujesz uruchamiać zapytania DB, możesz spojrzeć na JINQ, jak wspomniano powyżej, ale RetroLambda nie może go cofnąć, skorzystaj z serializowanych lambd.
Aby dodać kolejną alternatywę: Java 6 ma rozwiązanie dla bezpiecznych zapytań do bazy danych przy użyciu pakietu javax.persistence.criteria .
Chociaż muszę powiedzieć, że tak naprawdę nie jest to LINQ, ponieważ za pomocą LINQ można wyszukiwać dowolne IEnumerable.
Istnieje bardzo dobra biblioteka, której możesz użyć do tego.
Znajduje się tutaj: https://github.com/nicholas22/jpropel-light
Jednak Lambdas będzie dostępny dopiero w Javie 8, więc używanie go jest nieco inne i nie wydaje się tak naturalne.
Wygląda na to, że Linq, o którym wszyscy tutaj mówią, to tylko LinqToObjects. Które, jak wierzę, oferuje tylko funkcjonalność, którą można już dziś osiągnąć w Javie, ale z naprawdę brzydką składnią.
To, co widzę jako prawdziwą potęgę Linq w .Net, polega na tym, że wyrażeń lambda można używać w kontekście wymagającym Delegata lub Wyrażenia, a następnie zostaną one skompilowane do odpowiedniej formy. To pozwala na działanie takich rzeczy jak LinqToSql (lub cokolwiek innego niż LinqToObjects) i pozwala im mieć składnię identyczną jak LinqToObjects.
Wygląda na to, że wszystkie wyżej wymienione projekty oferują jedynie możliwości LinqToObjects. Co sprawia, że myślę, że funkcjonalność typu LinqToSql nie jest na horyzoncie dla Java.
W przypadku podstawowych kolekcji funkcjonalnych Java 8 ma wbudowane oprogramowanie, większość głównych języków JVM innych niż Java ma wbudowane (Scala, Clojure itp.). Możesz także dodać biblioteki lib dla wcześniejszych wersji Java.
Aby uzyskać pełny zintegrowany dostęp do bazy danych SQL, Scala (działa na JVM) ma Slick
W przypadku LINQ (LINQ to Objects) Java 8 będzie miała coś równoważnego, zobacz Project Lambda .
Ma przeliczalny jest LINQ to Objects rozszerzeniami takimi jak spożywczych . Ale w przypadku bardziej skomplikowanych rzeczy LINQ, takich jak Expression i ExpressionTree (są one potrzebne dla LINQ na SQL i innych dostawców LINQ, jeśli chcą dostarczyć coś zoptymalizowanego i rzeczywistego), nie ma jeszcze odpowiednika, ale może zobaczymy to w przyszłości :)
Ale nie sądzę, że w przyszłości będą istniały zapytania deklaratywne na Javie.
W Javie nie ma takiej funkcji. Korzystając z innego interfejsu API, uzyskasz tę funkcję. Załóżmy, że mamy Obiekt zwierzęcy zawierający nazwę i identyfikator. Mamy obiekt listy mający obiekty zwierzęce. Teraz, jeśli chcemy uzyskać wszystkie nazwy zwierząt, które zawierają „o” z obiektu listy. możemy napisać następujące zapytanie
from(animals).where("getName", contains("o")).all();
W powyższym zapytaniu wyszczególnione zostaną zwierzęta zawierające alfabet „o” w nazwie. Więcej informacji można znaleźć na poniższym blogu. http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
Sprawdź małe-q . (Pamiętaj, że obecnie nie możesz go pobrać).
Oto przykład dostosowany powyższy link:
Najpierw potrzebujemy zbioru niektórych danych, powiedzmy zestawu ciągów
String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };
Teraz chcemy wybrać tylko ciągi rozpoczynające się od „b”:
Query<String> stringsStartingWithB = new Query<String>(strings).where(
new Query.Func<String, Boolean>(){
public Boolean run(String in) {
return in.startsWith("b");
}
}
);
Żadne rzeczywiste dane nie zostały skopiowane ani nic w tym stylu, zostaną przetworzone, gdy tylko zaczniesz iterację:
for(String string : stringsStartingWithB ) {
System.out.println(string);
}
JaQu jest odpowiednikiem LINQ dla Java. Chociaż został opracowany dla bazy danych H2, powinien działać dla każdej bazy danych, ponieważ używa JDBC.
Być może nie jest to odpowiedź, na którą liczysz, ale jeśli jakaś część twojego kodu wymaga ciężkiej pracy nad kolekcjami (wyszukiwanie, sortowanie, filtrowanie, transformacje, analiza), możesz wziąć pod uwagę napisanie niektórych klas w Clojure lub Scali .
Ze względu na ich funkcjonalny charakter najlepsza jest praca z kolekcjami. Nie mam dużego doświadczenia ze Scalą, ale dzięki Clojure prawdopodobnie znajdziesz na wyciągnięcie ręki mocniejszego Linqa, a po skompilowaniu klasy, które stworzysz, będą bezproblemowo integrować się z resztą bazy kodu.
Anonimowy użytkownik wspomniał o innym, Diting :
Diting to biblioteka klas zapewniająca możliwości zapytań w kolekcjach za pomocą metod łańcuchowych i anonimowego interfejsu, takiego jak Linq w .NET. W przeciwieństwie do większości innych bibliotek kolekcji, które używają metod statycznych, wymagają iteracji całej kolekcji, Diting zapewnia podstawową klasę Enumerable, która zawiera odroczone łańcuchowe metody implementacji kwerendy na zbiorze lub tablicy.
Obsługiwane metody: dowolna, rzutowana, kontaktowa, zawiera, zliczaj, odrębna, elementAt, z wyjątkiem: first, firstOrDefault, groupBy, interset, join, last, lastOrDefault, ofType, orderBy, orderByDescending, wstecz, wybierz, wybierz Wiele, pojedynczy, singleOrDefault, pomiń , skipWhile, take, takeWhile, toArray, toArrayList, union, where
Scala.Teraz przeczytałem go i znalazłem jak linq, ale prostszy i bardziej nieczytelny. ale Scala może działać w systemie Linux, tak? csharp potrzebuje mono.
Był język programowania Pizza (rozszerzenie Java) i powinieneś go zobaczyć. - Wykorzystuje koncepcję „płynnych interfejsów” do kwerendowania danych w sposób deklaratywny i zasadniczo jest identyczny z wyrażeniami zapytań LINQ (http://en.wikipedia.org/wiki/Pizza_programming_language). Ale niestety nie było to ścigane, ale byłby to jeden ze sposobów, aby uzyskać coś podobnego do LINQ w Javie.
Nie ma odpowiednika LINQ dla Java. Ale istnieje część zewnętrznego API, który wygląda jak LINQ, taki jak https://github.com/nicholas22/jpropel-light , https://code.google.com/p/jaque/
możesz wypróbować tę bibliotekę: https://code.google.com/p/qood/
Oto kilka powodów, aby z niego korzystać: