Що таке еквівалент Java для LINQ? [зачинено]


820

Що таке еквівалент Java для LINQ?


4
Вони, схоже, є LINQ до SQL.
SLaks

8
Перевірте це: github.com/nicholas22/jpropel-light, реальний приклад: new String [] {"james", "john", "john", "eddie"} .wherewhere (beginWith ("j")). ToList () .distinct ();
NT_

1
Java ppl як і раніше використовує кілька операторів і циклів foreach, які можна вирішити Linq ...
om471987

1
Також для Scala w / full LINQ API: github.com/nicholas22/propelS
Scooterville

4
@craastad Оскільки хлопець .NET зараз в основному застряг у світі Java, я відчуваю твій біль. Вам слід спробувати Scala - функції / закриття першого класу, для розуміння (не те саме, що синтаксис запитів LINQ, але корисний у багатьох одних і тих же ситуаціях), уніфіковану систему типів, умовиводи типу, деякі зручні способи вирішення загального стирання типу ... все працює на JVM, взаємодіючи з Java. Плюс ще купа інших функціональних благ, таких як узгодження шаблону, тип варіанту тощо
Тім Гудман

Відповіді:


808

Для Java немає нічого подібного до LINQ.

...

Редагувати

Тепер з Java 8 ми знайомимося з API Stream , це подібний предмет при роботі з колекціями, але це не зовсім так, як Linq.

Якщо це ORM, який ви шукаєте, як Entity Framework, тоді ви можете спробувати Hibernate

:-)


9
є щось у плані? інтегрований у мову? Є номер JCP? тощо тощо
Cheeso

6
Дуже правда, хоча велика частина того, що робить LINQ так приємно, це те, наскільки глибоко вона інтегрована в мову та компілятор
AgileJon

11
Вибачте, "дуже правда" мала на увазі 280Z28. Я не знаю, чи є для цього JCP. LINQ потребував декількох змін мови C #, враховуючи швидкість роботи JCP, я б не затримував дихання.
AgileJon

12
Це неправильно. Див: stackoverflow.com/questions/10879761 / ...
Scooterville

23
LINQ - це специфікація, а не реалізація ... Ламбда-вирази є частиною LINQ. Усі проекти, що намагаються перенести LINQ на Java, є реалізаціями для конкретного сценарію (SQL, Об'єкти ...), але не покриває головну мету LINQ: Інтегрувати мовний запит у код. Зважаючи на це, наразі не існує реальної альтернативи, ні ініціативної, яка може вважатися альтернативою.
sesispla

154

Є альтернативне рішення, 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();

7
Рядок для імені стовпця, що означає, що компілятор та IDE автозаповнення не допоможуть проти помилок друку, а рефакторинг - це важко. Будь-які плани це змінити?
Екеву

2
Привіт, Екеву. Я думаю, що це буде дивним, і я намагався це зробити колись. Але в даний момент, з Java 8, Coollection є застарілою лібером. Можливо, це корисно найстарішим проектам ... Як ви думаєте?
19WAS85

1
@WagnerAndrade Остання комісія - 5-6 років тому. Я припускаю, що функціональність значною мірою була замінена Java 8? Також дуже класна назва :)
Абдул

145

Лямбди тепер доступні в Java 8 у формі JSR-335 - Lambda вирази для мови програмування JavaTM

ОНОВЛЕННЯ : Тепер випущено JDK8, який містить лямбда проекту. Варто захопити копію Java 8 в Action в даний час досі MEAP.

Прочитайте статті Брайана Геца, що стосуються лямбда, щоб гідно зрозуміти, як реалізуються лямбди в JDK8, а також зрозуміти потоки, внутрішню ітерацію, коротке замикання та посилання на конструктор. .

Я написав блог про деякі переваги використання лямбда в JDK8 під назвою "Сила стрілки" , також NetBeans 8 має велику підтримку перетворення конструкцій в JDK8, який я також блогував про міграцію в JDK 8 з NetBeans .


Чи не заплановано лямбда також бути на Java 7? Що з цим сталося?
BlueRaja - Danny Pflughoeft

7
Оракул купив Сонце (язиком у щоках). Java 7 зайняла занадто довго (5 років), тому лямбдас пропустив цей шорт-лист, це досить невтішно для мас. Це, як кажуть, Oracle схоже на те, що він збирає м'яч, і я думаю, що ми запланували на Яву 8 жовтня наступного року.
Бретт Райан

1
Зауважте, що стан Ламбди було оновлено ще раз, що тепер охоплює потоки, внутрішню ітерацію, коротке замикання та посилання на конструктор. Раджу всім прочитати новий документ.
Бретт Райан

6
Лямбда-вирази - це частина LINQ.
sesispla

4
@NeWNeO, якщо ви посилаєтесь на мову запиту в C #, то так, нічого подібного не стосується Java, проте, на мій досвід, більшість досвідчених розробників C # віддають перевагу лямбда-синтаксису над мовою запиту. Однак якщо ви, наприклад, посилаєтесь на LINQ-to-Entities, ви побачите, що лямбди в Java дозволять це та багато іншого. На Java 8 з'являється набагато більше, щоб увімкнути це, наприклад, захисні методи .
Бретт Райан

119

Ви можете вибрати елементи з колекції (та багато іншого) більш читабельним способом, скориставшись бібліотекою lambdaj

https://code.google.com/archive/p/lambdaj/

Він має деякі переваги перед бібліотекою Quaere, оскільки він не використовує жодної магічної струни, він повністю безпечний для типу і, на мою думку, пропонує більш читабельний DSL.


6
Це добре, але далеко не збирається створити запит і виконати його знову sql, xml, collection тощо.
bytebender

Чому я можу отримувати java.lang.ExceptionInInitializerError при використанні lambdaj select у користувацькому класі в моєму проекті Android?
topwik

1
+1 це дійсно добре для тих із нас, хто не піклується про SQL / XML та бажає лише більш легкого доступу до колекцій.
попіл999

101

Ви не знайдете еквівалента LINQ, якщо не будете використовувати javacc для створення власного еквівалента.

До того дня, коли хтось знайде життєздатний спосіб зробити це, є кілька хороших альтернатив, наприклад


github.com/TrigerSoft/jaque знайшов такий спосіб і дозволить створювати дерева виразів. У поєднанні з Java 8 Lambdas будь-яка ємність LINQ може бути реалізована з тими ж зусиллями, що і в .Net.
Костянтин Тригер

Дивіться цю відповідь для порівняння: stackoverflow.com/questions/25989449/…
Костянтин Тригер

49

LINQ до об'єктів - JAVA 8 додав API Stream, який додає підтримку операцій функціонального стилю в потоках значень:

Пакет java.util.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/


Не впевнений, чому читачі не звернули уваги на вашу відповідь, хоча API Stream є найближчим до LINQ!
Рафід

3
API Streams - це поганий жарт у порівнянні з LINQ.
Андрій Ронеа

1
Вибач людина, не означає бути грубим. Я шукав еквівалент LINQ після того, як відбив голову потоками API. Я просто хотів сказати, що це не справжній еквівалент, ось і все.
Андрій Ронеа

1
@ AndreiRînea Ви шукаєте постачальників LINQ (LINQ до XML, LINQ до JSON, LINQ до NHibernate тощо), які мають еквівалентну функціональність?
Разван Флавій Панда

2
Все, що мені було потрібно, - це засіб для згрупування та максимуму колекції. Я врешті-решт досяг успіху, але з великими зусиллями та занадто великим кодом.
Андрій Ронеа

29

Є проект під назвою quaere .

Це рамка Java, яка додає можливість запиту колекцій.

Примітка: За словами автора, проект більше не підтримується.


2
Quaere виглядає так, що надає трохи того, що надає LINQ, але питання в "еквіваленті"
AgileJon

6
Так це щось на кшталт LINQ, якщо не прямий еквівалент? Що принаймні звучить корисно
Брайан Агнеу

3
@AgileJon: Якби він справді мав на увазі еквівалент, він би не запитував. Він міг набрати from x in xs select xі дізнатися відповідь (ні).
kizzx2

18

Для Java існує багато еквівалентів LINQ, дивіться тут для порівняння.

Для рамки стилів Quaere / LINQ типу typefa , розгляньте можливість використання Querydsl . Querydsl підтримує колекції JPA / Hibernate, JDO, SQL та Java.

Я підтримую Querydsl, тому ця відповідь упереджена.


6
Посилання "подібні рамки" мертве. У вас ще є еквівалентна сторінка?
Лукас Едер

Коли ми отримаємо книгу QueryDSL? Або навіть доступні варіанти навчання? Ваша підтримка 404s.
кервін

16

ви можете використовувати scala, він схожий у синтаксисі і насправді, ймовірно, потужніший, ніж linq.


1
Esp Скала "для розуміння".
Ніко

10

Що стосується 2014 року, я, нарешті, можу сказати, що LINQ нарешті є в java 8. Тому більше не потрібно шукати альтернативу LINQ.


9

Тепер, коли Java 8 підтримує лямбда, можливо створити Java API, які дуже нагадують LINQ.

Jinq - одна з цих нових бібліотек стилю LINQ для Java.

Я розробник цієї бібліотеки. Він ґрунтується на п'ятирічних дослідженнях використання байт-коду для перекладу Java в запити до бази даних. Подібно до того, як D-LINQ C # є запитом, який розташовується поверх Entity Framework, Jinq може діяти як шар запиту, що сидить зверху JPA або jOOQ. Він підтримує агрегацію, групи та підзапити. Навіть Ерік Мейєр (творець LINQ) визнав Jinq .


8

Див. SBQL4J . Це безпечна сильна мова запитів, інтегрована з Java. Дозволяє писати складні та множити вкладені запити. Операторів дуже багато, методи Java можна викликати всередині запитів, як конструктори. Запити переводяться на чистий код Java (під час виконання немає відображення), тому виконання відбувається дуже швидко.

EDIT: Ну, поки що SBQL4J - це ТІЛЬКЕ розширення до мови Java, що дає можливості запитів, схожі на LINQ. Є такі цікаві проекти, як Quaere та JaQue, але вони є лише API, а не розширенням синтаксису / семантики з високою безпекою типу під час компіляції.


6
Ви можете згадати свою роль у проекті.
Thorbjørn Ravn Andersen

8

Реалізація Java LINQ в SQL . Забезпечує повну інтеграцію мови та більший набір функцій порівняно з .NET LINQ.


2
Чи можу я використовувати JaQue для читання / запису XML-файлів так само, як ми можемо робити з LINQ?
Хурам Маджед

7

Я спробував 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, але виглядає цікаво.


7

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

5

Ви можете спробувати мої бібліотечні колекції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 не може бути підпорядкований назад, не використовуйте серіалізовані лямбда.



4

Просто додамо ще одну альтернативу: Java 6 має рішення для безпечних для запитів баз даних за допомогою пакету javax.persistent.criteria .

Хоча я мушу сказати, що це насправді не LINQ, тому що за допомогою LINQ ви можете запитувати будь-який IEnumerable.


Так, це JPA API. Далеко від LINQ, але краще, ніж нічого. І можна сказати, що вона заснована вільно на API критерії сплячого режиму. Дивіться: docs.jboss.org/hibernate/core/3.6/reference/en-US/html/…
Хенді Іраван

4

Є дуже хороша бібліотека, яку ви можете використовувати для цього.

Розташований тут: https://github.com/nicholas22/jpropel-light

Лямбда буде доступна, поки не працює Java 8, тому використання її трохи відрізняється і не вважається природним.


4

Здається, що Linq, про який тут всі говорять, - це лише LinqToObjects. Я вважаю, що це лише функціонал, який вже сьогодні можна виконати на Java, але з по-справжньому некрасивим синтаксисом.

Що я бачу як справжню силу Linq в .Net, це те, що лямбда-вирази можуть використовуватися в контексті, що вимагає або Делегата, або Виразу, і потім буде складено у відповідну форму. Це те, що дозволяє таким речам, як LinqToSql (або що-небудь інше, ніж LinqToObjects), і дозволяє їм мати синтаксис, ідентичний LinqToObjects.

Схоже, всі згадані вище проекти пропонують лише можливості LinqToObjects. Що означає, що функціональність типу LinqToSql не на горизонті для Java.


4

Для базових функціональних колекцій Java 8 вбудована, більшість основних мов JVM, що не є Java, вбудовані у неї (Scala, Clojure тощо), і ви можете отримати додаткові лібри для попередніх версій Java.

Для повного мовного інтегрованого доступу до бази даних SQL, Scala (працює на JVM) має Slick


3

Щодо LINQ (LINQ до об'єктів), Java 8 матиме щось еквівалентне, див. Проект Lambda .

Він має перелічувальний в LINQ до об'єктів розширенням як харчування . Але для більш складних речей LINQ, таких як Expression та ExpressionTree (вони потрібні для LINQ для SQL та інших постачальників LINQ, якщо вони хочуть забезпечити щось оптимізоване та реальне), ще немає жодного еквівалента, але, можливо, ми це побачимо в майбутньому :)

Але я не думаю, що в майбутньому на Java не буде нічого подібного до запитів декларацій.


2

У Java немає такої особливості. Використовуючи інший API, ви отримаєте цю функцію. Припустімо, у нас є об’єкт тварини, що містить ім'я та ідентифікатор. У нас є список об'єктів, що мають тваринні об'єкти. Тепер, якщо ми хочемо отримати від об'єкта списку все ім'я тварини, яке містить 'o'. ми можемо написати наступний запит

from(animals).where("getName", contains("o")).all();

Зверху над запитом буде вказано список тварин, який містить ім'я 'o' у своєму імені. Більше інформації просимо за допомогою наступного блогу. http://javaworldwide.blogspot.in/2012/09/linq-in-java.html


2

Перевірте 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);
}

1

JaQu - еквівалент LINQ для Java. Хоча він був розроблений для бази даних H2, він повинен працювати для будь-якої бази даних, оскільки він використовує JDBC.


1

Можливо, не відповідь, на яку ви сподіваєтесь, але якщо якась частина коду потребує важкої роботи над колекціями (пошук, сортування, фільтрування, перетворення, аналіз), ви можете взяти до уваги, щоб написати кілька класів у Clojure або Scala .

Через їх функціональну природу робота з колекціями - це те, що їм найкраще. Я не маю великого досвіду роботи зі Scala, але з Clojure ви, мабуть, знайдете більш потужний Linq під рукою, і коли складені, класи, які ви будете виробляти, інтегрували б безперешкодно решту з базою коду.


1
Groovy або jRuby також були б життєздатними кандидатами, оскільки всі вони мають набагато більш функціональну природу.
cdeszaq

1

Анонімний користувач згадав ще одного, Diting :

Дитинг - це бібліотека класів, що надає можливості запитів у колекціях за допомогою доступних методів та анонімного інтерфейсу, як Linq у .NET. На відміну від більшості інших бібліотек колекцій, які використовують статичні методи, потребують повторення цілої колекції, Diting надає основне число Численні класи, які містять відкладені методи, доступні для впровадження запиту на колекцію чи масив.

Підтримувані способи: будь-який, керований, контактний, містить, рахує, відрізний, elementAt, за винятком першого, першогоOrDefault, groupBy, інтерсету, приєднання, останнього, lastOrDefault, ofType, orderBy, orderByDescending, зворотний, виберіть, selectMany, одиночний, singleOrDefault, пропустити , skipWhile, взяти, takeWhile, toArray, toArrayList, union, де


1

Scala.Зараз я зірка прочитала його, і знайшла його як linq, але простішою та нечитабельнішою. але Scala може працювати в Linux, так? csharp потрібно моно.


1
Scala потрібен час виконання Java: вона не обов'язково працюватиме на голій установці Linux, залежно від того, які компоненти ви встановлюєте.
Rup

@Rup Є повністю сумісний JRE для GNU / Linux, і Mono не є повністю сумісною реалізацією .NET.
Відображати ім'я

@Sarge Це не було моєю суттю, але Mono запускає LINQ досить добре, чи не так? Крім того, зараз є власний .Net Core для Microsoft .
Rup

(GNU /) Linux - не єдина платформа, окрім Windows, і JRE існує для найрізноманітніших платформ. Mono не повністю реалізує все, наприклад, немає WPF.
Відображення імені

0

Була мова програмування Pizza (розширення Java), і ви повинні ознайомитися з нею. - Він використовує поняття "вільні інтерфейси" для запиту даних декларативним чином, і це в принципі ідентично виразам LINQ без запитів (http://en.wikipedia.org/wiki/Pizza_programming_language). Але, на жаль, його не переслідували, але це був би один із способів отримати щось схоже на LINQ в Java.


1
Впевнений, що його переслідували, тільки не під назвою "Піца". Генеріки з Pizza об'єдналися в GJ, який потім став компілятором Java 1.3 (хоча генерики були заховані за прапором до 1,5). Тим часом ... решта ідей, а також кілька додаткових, стали Scala.
Кевін Райт

Дякую за цю інформацію, звичайно, Скала - це хороший момент. Але ці здібності там, де не інтегровані в мову Java. Ви можете використовувати мову Scala, щоб реалізувати приємний код запиту та використовувати отриманий бінарний, а потім від Java.
Ніко

Також дивіться ONGL на веб-сайті commons.apache.org/proper/commons-ognl , який використовується та зберігається.
Ніко


0

ви можете спробувати цю бібліотеку: https://code.google.com/p/qood/

Ось кілька причин використовувати його:

  1. легкий: лише 9 публічних інтерфейсів / класів для навчання.
  2. запит на зразок SQL: група підтримки, замовлення, ліве з'єднання, формула, тощо.
  3. для великих даних: використовуйте File (QFS) замість Heap Memory.
  4. спробуйте вирішити невідповідність об'єктно-реляційного опору .
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.