Czy są jakieś biblioteki w Javie, które są bliskie zapewnienia funkcjonalności Linq?
Czy są jakieś biblioteki w Javie, które są bliskie zapewnienia funkcjonalności Linq?
Odpowiedzi:
Aby uzyskać pełną składnię zapytań LINQ, potrzebna byłaby aktualizacja specyfikacji języka i kompilatorów obsługujących nowe słowa kluczowe i strukturę składni. To znacznie wykracza poza większość czytelników tutaj.
Aby uzyskać podobną do Linqa składnię łańcucha metod w Javie, która wygląda i działa jak w C #, potrzebujesz dwóch rzeczy, których Java nie obsługuje; metody rozszerzenia (metody statyczne, które można zastosować do instancji tak, jakby była to metoda instancji) oraz wyrażenia lambda (anonimowi delegaci). Te dwa elementy można jednak sfałszować za pomocą istniejących konstrukcji Java, jeśli chcesz ponieść trochę dodatkowej gadatliwości kodowania. Jedną z rzeczy, które szczególnie mnie interesują w Javie, jest możliwość tworzenia anonimowych implementacji interfejsu; zastosowane do interfejsu z pojedynczą czystą funkcją, która zasadniczo pozwala na proste anonimowe delegowanie, pod warunkiem, że masz interfejs dla każdej podpisu metody, której potrzebujesz.
Zatem strona IEnumerable (Iterable for Javaheads) Linq, jako łańcuch metod, powinna być możliwa do przybliżenia w Javie; w zasadzie zaimplementowałbyś go jako płynny interfejs kontrolujący monadę. Potrzebujesz takiej klasy, jak LinqIterable
implementacja Iterable, która:
Prawdopodobnie mógłbyś zdefiniować „płynną” bibliotekę, która pozwoliłaby na stwierdzenie takie jak:
Map<String, Integer> results = Linq.FromIterable(sourceList)
.Where(new Predicate{public bool Op(SomeStruct in){return in.SomeString == "criteria";}})
.OrderBy(new Func{public String Op(SomeStruct in){return in.SomeOtherString;}})
.Select(new Func{public SomeOtherStruct Op(SomeStruct in){return new SomeOtherStruct(in.SomeOtherString, in.SomeInt);}})
.ToMap(new Func{public String Op(SomeOtherStruct in){return in.StringField;}},
new Func{public Integer Op(SomeOtherStruct in){return in.IntField;}});
Stworzenie faktycznej biblioteki jest ćwiczeniem znacznie wykraczającym poza zakres odpowiedzi w internetowych pytaniach i odpowiedziach. Powiedziałem tylko, że to możliwe, a nie łatwe.
Drzewa ekspresyjne nie są nauką rakietową, ale wdrożenie tego, co .NET ma w tym obszarze, byłoby znaczącym projektem; nie tylko potrzebujesz zdolności do budowania drzewa wyrażeń, musisz także być w stanie „skompilować” to drzewo w locie za pomocą emitowanych kodów bajtowych; Nie wiem, czy odbicie Javy jest tak potężne.
Widzieć:
Nie. Linq wymaga wielu funkcji językowych, których Java po prostu nie ma
Użyj Scali , z powodów wyjaśnionych tutaj :
użyj portu Scala .NET. Daje ci pełny natywny dostęp do wszystkiego w .NET, który oczywiście obejmuje LINQ.
Jeśli nie możesz, możesz spróbować użyć bibliotek takich jak functionjava lub lambdaj , ale tak naprawdę nie zbliżysz się do LINQ.
Dodałbym guawa do listy bibliotek, które mogą pomóc ci osiągnąć niektóre rzeczy, które robi LINQ.
Ale jak zauważyli inni, nie ma odpowiednika w czystej Javie.
Możesz użyć Korma , DSL do zapytań SQL napisanych w Clojure.
Składnia jest dość zgrabna:
(select user
(with address)
(fields :firstName :lastName :address.state)
(where {:email "korma@sqlkorma.com"}))
Możesz to łatwo wywołać z Javy, importując odpowiednie biblioteki Clojure i po prostu używając zwykłego interfejsu Clojure / Java.
W Javie nie ma natywnej funkcji, która naśladuje linq. Istnieje jednak kilka interfejsów API, które zapewniają tę samą funkcjonalność.
Na przykład ten post na blogu zawiera niestandardowy słoik do replikacji linq.
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
A to jest przykładowe użycie interfejsu API z postu:
Załóżmy, że mamy obiekt Animal zawierający nazwę i identyfikator, który jest reprezentowany przez listę animals
. Jeśli chcemy uzyskać z listy wszystkie nazwy zwierząt, które zawierają „o” animals
, możemy napisać następujące zapytanie
from(animals).where("getName", contains("o")).all();
Istnieją dwa inne interfejsy API, o których mowa w blogu: lambdaJ i jLinq
where("getName", ...)
.