Який найкращий еквівалент Java для Linq? [зачинено]


17

Чи є на Яві бібліотеки, які наближаються до надання функціональності Linq?


1
Я припускаю, що ви маєте на увазі "синтаксис LINQ", а не "функціональність LINQ". Є багато бібліотек, які забезпечують однаковий функціонал :-)
mikera

Java-еквівалент, швидше за все, Groovy . За рахунок втрати типу безпеки, хоча
гнат

Відповіді:


20

Щоб отримати повний синтаксис запитів LINQ, вам знадобиться оновлення специфікації мови та компіляторів, що підтримують нові ключові слова та структуру синтаксису. Це далеко поза більшості читачів.

Для того, щоб отримати синтаксис синтаксису ланцюга методів у Java, який виглядає і працює як те, що в C #, вам потрібно дві речі, які Java не підтримує; методи розширення (статичні методи, які можна застосувати до екземпляра, як якщо б це був метод екземпляра), і лямбда-вирази (анонімні делегати). Тим не менше, ці два можуть бути підроблені існуючими конструкціями Java, якщо ви бажаєте зазнати трохи додаткового багатослівного кодування. Одне, що мене особливо вражає щодо Java, - це можливість створювати анонімні реалізації інтерфейсу; застосовано до інтерфейсу з єдиною чистою функцією, яка в основному дозволяє прості анонімні делегати, якщо у вас є інтерфейс для кожного підпису методу, який вам знадобиться.

Отже, сторона Linq (Iterable для Javaheads) Linq, як ланцюжок методів, повинна мати можливість наближення в Java; ви в основному реалізуєте це як вільний інтерфейс, який управляє монадою. Вам потрібен такий клас, як LinqIterable, реалізуючи Iterable, що:

  • може перетворити будь-який Iterable вхід у екземпляр LinqIterable
  • має методи для обробки базових списків, такі як фільтрування, групування, конкатенація, перетину, упорядкування тощо, які приймають однофункціональні інтерфейси та створюють нові LinqIterables, дозволяючи ланцюжок цих методів, сподіваємось, "ледачим" способом.
  • має методи перетворення LinqIterable назад у "конкретні" об'єкти, такі як ToList, ToArray, ToMap тощо

Отже, ви, ймовірно, могли б визначити "вільну" бібліотеку, яка дозволила б такий вираз:

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

Створення фактичної бібліотеки - це вправа, що далеко виходить за рамки відповіді в Інтернет-запитаннях. Я просто сказав, що це можливо, не просто.

Дерева виразів не є ракетною наукою, але це був би вагомий проект для впровадження того, що .NET має у цій галузі; не тільки вам потрібна здатність будувати дерево виразів, ви повинні вміти «складати» це дерево на льоту, використовуючи випромінювані байт-коди; Я не знаю, чи відображення Яви настільки сильне.


2
Досить смішно методи розширення та лямбда-вирази є обома в Java 8. Можливо, LINQ на шляху?
lxs

4
Добре, якщо у вас є методи розширення та лямбда, у вас є безліч зусиль Linq Linq без величезних зусиль. Як я вже сказав, як і раніше, потрібно буде змінити специфікацію Java, щоб дозволити ключовим словам, які роблять запит Linq, але, чесно кажучи, у щоденному використанні Linq я не знайшов занадто багато запитів, які не так просто виражений у вигляді ланцюга методів, і компілятор в значній мірі перетворює синтаксис Linq у ланцюги методів (існують плагіни VS, які можуть конвертувати 1: 1 між більшістю запитів і ланцюгів). Наступним справжнім кроком буде дерево виразів (Queryable Linq).
KeithS

8

Побачити:

  • /programming/1217228/what-is-the-java-equivalent-for-linq - Деякі кажуть, що немає еквівалента, або ви можете використовувати Lambdaj, щоб імітувати його.
  • /programming/346721/linq-for-java-tool - Є згадка, що перед Java 8 ви також можете використовувати колекції Google, щоб підробити її, і що мова Scala підтримує її як мовну особливість, ( Скала - ще одна популярна мова в СВМ).
  • http://www.infoq.com/news/2007/09/quaere-linq - бібліотека Java, яка теоретично забезпечує функціональність LINQ (я сам цього не пробував).

1
Ви б не хотіли трохи розширити те, що має кожен з цих ресурсів, і чому ви рекомендуєте їх відповідати на поставлене запитання? "Відповіді лише на посилання" не дуже вітаються на біржі стеків
gnat

Хм, я думаю, це випадок, на який уже відповіли на це запитання - чи слід модифікувати як дублікат?
Martijn Verburg

1
@MartijnVerburg - ми не можемо позначати питання як копії на сайтах. Відповіді дійсно потрібно мати можливість самостійно стояти.
ChrisF

Відредаговано, сподіваємось, зараз це трохи корисніше.
Martijn Verburg

5

Ні. Linq вимагає безлічі функцій, які мають лише Java


4
У Java є дженерики.
Йонас

6
@Jonas: Це правда, але чи є вони насправді достатньо сильними, щоб підтримувати LINQ - інша справа.
DeadMG

2
@DeadMG все ще у Java є дженерики.
Махмуд Хоссам

Відредаговано, щоб видалити посилання на дженерики
Tom Squires

3

Використовуйте Scala з пояснених тут причин :

використовувати порт .NET Scala. Він надає повний вихідний доступ до всього в .NET, що, очевидно, включає LINQ.

Якщо ви не можете, ви можете спробувати використовувати libs, як functionjava або lambdaj , але ви не наблизитесь до LINQ.


1
Scala не містить нічого подібного до Linq без бібліотек.
Йонас

1
@Jonas: Так? Java не містить нічого подібного до Linq з бібліотеками.
back2dos

@ back2dos: Так, тому потрібно відповідати бібліотекою.
Йонас

1
@Jonas: Стандартна бібліотека Scala схожа на LINQ. Або навпаки: LINQ - це лише набір функціональних ідіом програмування для C #. Більше про це тут .
back2dos

@ back2dos: Дякую за чудове посилання, я взяв свободу включити його.
Ландей

2

Я додав би guava до списку бібліотек, які можуть допомогти вам досягти деяких речей, які робить LINQ.

Але як зазначали інші, у чистої Java немає еквівалента.


Ви б не хотіли пояснити детальніше про те, що це робить, і чому ви рекомендуєте це відповісти на поставлене запитання? "Відповіді лише на посилання" не дуже вітаються на біржі стеків
gnat

2

Ви можете використовувати Корму , DSL для запитів SQL, написаних у Clojure.

Синтаксис досить акуратний:

(select user
  (with address)
  (fields :firstName :lastName :address.state)
  (where {:email "korma@sqlkorma.com"}))

Ви можете легко зателефонувати до цього з Java, імпортуючи відповідні бібліотеки Clojure та просто скориставшись звичайним інтеропом Clojure / Java.


Отже, це буде імітувати Linq над SQL, а не LINQ над об'єктами, правда?
Робота

@Job: так, він призначений для SQL. Хоча я не бачу жодної причини, щоб її не можна було також розширити / адаптувати для об’єктів.
mikera

2

У Java не існує рідної функції, яка імітує linq. Однак існує кілька API, які забезпечують однаковий функціонал.

Наприклад, у цій публікації в блозі є спеціальна баночка для копіювання linq.
http://javaworldwide.blogspot.in/2012/09/linq-in-java.html

І це приклад використання API від публікації:

Припустимо, у нас є об'єкт Animal, що містить ім'я та ідентифікатор, який представлений списком animals. Якщо ми хочемо отримати зі списку всі назви тварин, які містять "o" animals, ми можемо написати наступний запит

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

Є ще два API, на які посилається у публікації блогу: lambdaJ та jLinq


1
Я боюся, що втрата як перевірки статичного типу, так і перевірки самого існування члена класу - трохи крута ціна, щоб зателефонувати на такий дзвінок where("getName", ...).
9000
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.