Що таке еквівалент Java для LINQ?
Що таке еквівалент Java для LINQ?
Відповіді:
Для Java немає нічого подібного до LINQ.
...
Редагувати
Тепер з Java 8 ми знайомимося з API Stream , це подібний предмет при роботі з колекціями, але це не зовсім так, як Linq.
Якщо це ORM, який ви шукаєте, як Entity Framework, тоді ви можете спробувати Hibernate
:-)
Є альтернативне рішення, Coollection .
Coolection не претендує на нову лямбда, проте ми оточені старими застарілими проектами Java, де ця ліб допоможе. Це дуже просто у використанні та розширенні, охоплюючи лише найбільш використовувані дії ітерації над колекціями, наприклад:
from(people).where("name", eq("Arthur")).first();
from(people).where("age", lessThan(20)).all();
from(people).where("name", not(contains("Francine"))).all();
Лямбди тепер доступні в Java 8 у формі JSR-335 - Lambda вирази для мови програмування JavaTM
ОНОВЛЕННЯ : Тепер випущено JDK8, який містить лямбда проекту. Варто захопити копію Java 8 в Action в даний час досі MEAP.
Прочитайте статті Брайана Геца, що стосуються лямбда, щоб гідно зрозуміти, як реалізуються лямбди в JDK8, а також зрозуміти потоки, внутрішню ітерацію, коротке замикання та посилання на конструктор. .
Я написав блог про деякі переваги використання лямбда в JDK8 під назвою "Сила стрілки" , також NetBeans 8 має велику підтримку перетворення конструкцій в JDK8, який я також блогував про міграцію в JDK 8 з NetBeans .
Ви можете вибрати елементи з колекції (та багато іншого) більш читабельним способом, скориставшись бібліотекою lambdaj
https://code.google.com/archive/p/lambdaj/
Він має деякі переваги перед бібліотекою Quaere, оскільки він не використовує жодної магічної струни, він повністю безпечний для типу і, на мою думку, пропонує більш читабельний DSL.
Ви не знайдете еквівалента LINQ, якщо не будете використовувати javacc для створення власного еквівалента.
До того дня, коли хтось знайде життєздатний спосіб зробити це, є кілька хороших альтернатив, наприклад
LINQ до об'єктів - JAVA 8 додав API Stream, який додає підтримку операцій функціонального стилю в потоках значень:
Java 8 Пояснено: Застосування лямбдаз до колекцій Java
LINQ для SQL / NHibernate / тощо. (запит до бази даних) - Одним із варіантів було б використовувати JINQ, який також використовує нові функції JAVA 8 і був випущений 26 лютого 2014 року в Github: https://github.com/my2iu/Jinq
Jinq надає розробникам простий і природний спосіб писати запити до бази даних на Java. Ви можете обробляти дані бази даних, як звичайні об'єкти Java, що зберігаються в колекціях. Ви можете перебирати і фільтрувати їх за допомогою звичайних команд Java, і весь ваш код буде автоматично переведений в оптимізовані запити до бази даних. Нарешті, для Java доступні запити у стилі LINQ!
Сайт проекту JINQ: http://www.jinq.org/
Є проект під назвою quaere .
Це рамка Java, яка додає можливість запиту колекцій.
Примітка: За словами автора, проект більше не підтримується.
from x in xs select x
і дізнатися відповідь (ні).
Для Java існує багато еквівалентів LINQ, дивіться тут для порівняння.
Для рамки стилів Quaere / LINQ типу typefa , розгляньте можливість використання Querydsl . Querydsl підтримує колекції JPA / Hibernate, JDO, SQL та Java.
Я підтримую Querydsl, тому ця відповідь упереджена.
Що стосується 2014 року, я, нарешті, можу сказати, що LINQ нарешті є в java 8. Тому більше не потрібно шукати альтернативу LINQ.
Тепер, коли Java 8 підтримує лямбда, можливо створити Java API, які дуже нагадують LINQ.
Jinq - одна з цих нових бібліотек стилю LINQ для Java.
Я розробник цієї бібліотеки. Він ґрунтується на п'ятирічних дослідженнях використання байт-коду для перекладу Java в запити до бази даних. Подібно до того, як D-LINQ C # є запитом, який розташовується поверх Entity Framework, Jinq може діяти як шар запиту, що сидить зверху JPA або jOOQ. Він підтримує агрегацію, групи та підзапити. Навіть Ерік Мейєр (творець LINQ) визнав Jinq .
Див. SBQL4J . Це безпечна сильна мова запитів, інтегрована з Java. Дозволяє писати складні та множити вкладені запити. Операторів дуже багато, методи Java можна викликати всередині запитів, як конструктори. Запити переводяться на чистий код Java (під час виконання немає відображення), тому виконання відбувається дуже швидко.
EDIT: Ну, поки що SBQL4J - це ТІЛЬКЕ розширення до мови Java, що дає можливості запитів, схожі на LINQ. Є такі цікаві проекти, як Quaere та JaQue, але вони є лише API, а не розширенням синтаксису / семантики з високою безпекою типу під час компіляції.
Реалізація Java LINQ в SQL . Забезпечує повну інтеграцію мови та більший набір функцій порівняно з .NET LINQ.
Я спробував guava-бібліотеки від google. Він, FluentIterable
який, на мою думку, близький до LINQ. Також див. 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();
}
});
Здається, це велика бібліотека для Java. Звичайно, не настільки просто, як LINQ, але виглядає цікаво.
https://code.google.com/p/joquery/
Підтримує різні можливості,
З огляду на колекцію,
Collection<Dto> testList = new ArrayList<>();
типу,
class Dto
{
private int id;
private String text;
public int getId()
{
return id;
}
public int getText()
{
return text;
}
}
Фільтр
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();
Також,
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"});
Сортування (також доступне для Java 7)
Filter<Dto> query = CQ.<Dto>filter(testList)
.orderBy()
.property(Dto::getId)
.property(Dto::getName)
Collection<Dto> sorted = query.list();
Групування (також доступне для Java 7)
GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
.group()
.groupBy(Dto::getId)
Collection<Grouping<Integer,Dto>> grouped = query.list();
Приєднується (також доступний для Java 7)
Дано,
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<>();
Можна приєднатися, як
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();
Вирази
Filter<Dto> query = CQ.<Dto>filter()
.from(testList)
.where()
.exec(s -> s.getId() + 1).eq().value(2);
Ви можете спробувати мої бібліотечні колекціїQuery . Це дозволяє запускати LINQ як запити над колекціями об'єктів. Ви повинні пройти предикат, як і в LINQ. Якщо ви використовуєте java6 / 7, ніж вам потрібно використовувати старий синтаксис з інтерфейсами:
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();
Ви також можете використовувати його в Java8 або в старому Java з RetroLambda і його плагіном gradle , тоді у вас з'явиться новий фантазійний синтаксис:
List<String> names = Queryable.from(people)
.filter(p->p.age>20)
.map (p->p.name)
.toList();
Якщо вам потрібно запустити запити БД, тоді ви можете подивитися на JINQ, як згадувалося вище, але RetroLambda не може бути підпорядкований назад, не використовуйте серіалізовані лямбда.
Просто додамо ще одну альтернативу: Java 6 має рішення для безпечних для запитів баз даних за допомогою пакету javax.persistent.criteria .
Хоча я мушу сказати, що це насправді не LINQ, тому що за допомогою LINQ ви можете запитувати будь-який IEnumerable.
Є дуже хороша бібліотека, яку ви можете використовувати для цього.
Розташований тут: https://github.com/nicholas22/jpropel-light
Лямбда буде доступна, поки не працює Java 8, тому використання її трохи відрізняється і не вважається природним.
Здається, що Linq, про який тут всі говорять, - це лише LinqToObjects. Я вважаю, що це лише функціонал, який вже сьогодні можна виконати на Java, але з по-справжньому некрасивим синтаксисом.
Що я бачу як справжню силу Linq в .Net, це те, що лямбда-вирази можуть використовуватися в контексті, що вимагає або Делегата, або Виразу, і потім буде складено у відповідну форму. Це те, що дозволяє таким речам, як LinqToSql (або що-небудь інше, ніж LinqToObjects), і дозволяє їм мати синтаксис, ідентичний LinqToObjects.
Схоже, всі згадані вище проекти пропонують лише можливості LinqToObjects. Що означає, що функціональність типу LinqToSql не на горизонті для Java.
Для базових функціональних колекцій Java 8 вбудована, більшість основних мов JVM, що не є Java, вбудовані у неї (Scala, Clojure тощо), і ви можете отримати додаткові лібри для попередніх версій Java.
Для повного мовного інтегрованого доступу до бази даних SQL, Scala (працює на JVM) має Slick
Щодо LINQ (LINQ до об'єктів), Java 8 матиме щось еквівалентне, див. Проект Lambda .
Він має перелічувальний в LINQ до об'єктів розширенням як харчування . Але для більш складних речей LINQ, таких як Expression та ExpressionTree (вони потрібні для LINQ для SQL та інших постачальників LINQ, якщо вони хочуть забезпечити щось оптимізоване та реальне), ще немає жодного еквівалента, але, можливо, ми це побачимо в майбутньому :)
Але я не думаю, що в майбутньому на Java не буде нічого подібного до запитів декларацій.
У Java немає такої особливості. Використовуючи інший API, ви отримаєте цю функцію. Припустімо, у нас є об’єкт тварини, що містить ім'я та ідентифікатор. У нас є список об'єктів, що мають тваринні об'єкти. Тепер, якщо ми хочемо отримати від об'єкта списку все ім'я тварини, яке містить 'o'. ми можемо написати наступний запит
from(animals).where("getName", contains("o")).all();
Зверху над запитом буде вказано список тварин, який містить ім'я 'o' у своєму імені. Більше інформації просимо за допомогою наступного блогу. http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
Перевірте tiny-q . (Зауважте, що наразі ви не можете його завантажити.)
Ось приклад адаптованого вище посилання:
Спочатку нам потрібна збірка деяких даних, скажімо, набір рядків
String[] strings = { "bla", "mla", "bura", "bala", "mura", "buma" };
Тепер ми хочемо вибрати лише ті рядки, які починаються з "b":
Query<String> stringsStartingWithB = new Query<String>(strings).where(
new Query.Func<String, Boolean>(){
public Boolean run(String in) {
return in.startsWith("b");
}
}
);
Жодні фактичні дані, перенесені не скопійовані, або щось подібне, вони обробляться, як тільки ви почнете ітерацію:
for(String string : stringsStartingWithB ) {
System.out.println(string);
}
JaQu - еквівалент LINQ для Java. Хоча він був розроблений для бази даних H2, він повинен працювати для будь-якої бази даних, оскільки він використовує JDBC.
Можливо, не відповідь, на яку ви сподіваєтесь, але якщо якась частина коду потребує важкої роботи над колекціями (пошук, сортування, фільтрування, перетворення, аналіз), ви можете взяти до уваги, щоб написати кілька класів у Clojure або Scala .
Через їх функціональну природу робота з колекціями - це те, що їм найкраще. Я не маю великого досвіду роботи зі Scala, але з Clojure ви, мабуть, знайдете більш потужний Linq під рукою, і коли складені, класи, які ви будете виробляти, інтегрували б безперешкодно решту з базою коду.
Анонімний користувач згадав ще одного, Diting :
Дитинг - це бібліотека класів, що надає можливості запитів у колекціях за допомогою доступних методів та анонімного інтерфейсу, як Linq у .NET. На відміну від більшості інших бібліотек колекцій, які використовують статичні методи, потребують повторення цілої колекції, Diting надає основне число Численні класи, які містять відкладені методи, доступні для впровадження запиту на колекцію чи масив.
Підтримувані способи: будь-який, керований, контактний, містить, рахує, відрізний, elementAt, за винятком першого, першогоOrDefault, groupBy, інтерсету, приєднання, останнього, lastOrDefault, ofType, orderBy, orderByDescending, зворотний, виберіть, selectMany, одиночний, singleOrDefault, пропустити , skipWhile, взяти, takeWhile, toArray, toArrayList, union, де
Scala.Зараз я зірка прочитала його, і знайшла його як linq, але простішою та нечитабельнішою. але Scala може працювати в Linux, так? csharp потрібно моно.
Була мова програмування Pizza (розширення Java), і ви повинні ознайомитися з нею. - Він використовує поняття "вільні інтерфейси" для запиту даних декларативним чином, і це в принципі ідентично виразам LINQ без запитів (http://en.wikipedia.org/wiki/Pizza_programming_language). Але, на жаль, його не переслідували, але це був би один із способів отримати щось схоже на LINQ в Java.
Для Java немає еквівалента LINQ. Але є деякі зовнішні API, схожі на LINQ, такі як https://github.com/nicholas22/jpropel-light , https://code.google.com/p/jaque/
ви можете спробувати цю бібліотеку: https://code.google.com/p/qood/
Ось кілька причин використовувати його: