Что такое Java-эквивалент для LINQ?
Что такое Java-эквивалент для LINQ?
Ответы:
Нет ничего похожего на LINQ для Java.
...
редактировать
Теперь с Java 8 мы познакомились с Stream API , это похоже на то, что происходит с коллекциями, но это не совсем то же самое, что 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 - Лямбда-выражения для языка программирования JavaTM
ОБНОВЛЕНИЕ : JDK8 теперь выпущен, который содержит лямбда-проект. Стоит взять копию Java 8 в действии, в настоящее время все еще MEAP.
Прочитайте статьи Брайана Гетца, относящиеся к лямбдам, для приличного понимания того, как лямбды реализованы в JDK8, а также для понимания потоков, внутренней итерации, коротких замыканий и ссылок на конструкторы. Также ознакомьтесь с JSR выше, чтобы получить дополнительные примеры ,
Я написал блог о преимуществах использования лямбда-выражений в JDK8 под названием «Сила стрелки» , а также в NetBeans 8 есть отличная поддержка для преобразования конструкций в JDK8, о котором я также писал в блоге о переходе на JDK 8 с NetBeans .
Вы можете выбрать элементы в коллекции (и многое другое) более читабельным способом, используя библиотеку lambdaj
https://code.google.com/archive/p/lambdaj/
Она имеет некоторые преимущества перед библиотекой Quaere, потому что она не использует магическую строку, она полностью безопасна для типов и, на мой взгляд, предлагает более читаемый DSL.
Вы не найдете эквивалент LINQ, если не используете javacc для создания собственного эквивалента.
До того дня, когда кто-то найдет жизнеспособный способ сделать это, есть несколько хороших альтернатив, таких как
LINQ to Objects - JAVA 8 добавил Stream API, который добавляет поддержку операций функционального стиля над потоками значений:
Объяснение Java 8: применение лямбд к коллекциям Java
LINQ to SQL / NHibernate / и т. Д. (запросы к базе данных). Одним из вариантов будет использование JINQ, который также использует новые функции JAVA 8 и был выпущен 26 февраля 2014 года на Github: https://github.com/my2iu/Jinq
Jinq предоставляет разработчикам простой и естественный способ написания запросов к базе данных на Java. Вы можете обрабатывать данные базы данных как обычные объекты Java, хранящиеся в коллекциях. Вы можете перебирать их и фильтровать, используя обычные команды Java, и весь ваш код будет автоматически преобразован в оптимизированные запросы к базе данных. Наконец, запросы в стиле LINQ доступны для Java!
Сайт проекта JINQ: http://www.jinq.org/
Есть проект под названием quaere .
Это среда Java, которая добавляет возможность запрашивать коллекции.
Примечание: по словам автора, проект больше не поддерживается.
from x in xs select x
и узнать ответ (нет).
Есть много эквивалентов LINQ для Java, см. Здесь для сравнения.
Для безопасной среды стиля Quaere / LINQ рассмотрите возможность использования Querydsl . Querydsl поддерживает коллекции JPA / Hibernate, JDO, SQL и Java.
Я поддерживаю Querydsl, поэтому этот ответ предвзят.
Как и в 2014 году, я могу наконец сказать, что LINQ наконец-то появился в java 8. Так что больше не нужно искать альтернативу LINQ.
Теперь, когда Java 8 поддерживает лямбда-выражения, можно создавать API-интерфейсы Java, которые очень похожи на LINQ.
Jinq - одна из этих новых библиотек в стиле LINQ для Java.
Я разработчик этой библиотеки. Он основан на пятилетнем исследовании использования анализа байт-кода для перевода Java в запросы к базе данных. Подобно тому, как D-LINQ в C # является слоем запросов, который находится поверх Entity Framework, Jinq может выступать в качестве слоя запросов, расположенного поверх JPA или jOOQ. Он поддерживает агрегацию, группы и подзапросы. Даже Эрик Мейер (создатель LINQ) признал Jinq .
Смотрите SBQL4J . Это безопасный по типу язык строгих запросов, интегрированный с Java. Позволяет писать сложные и многократно вложенные запросы. Операторов очень много, внутри запросов можно вызывать методы Java в качестве конструкторов. Запросы транслируются в чистый Java-код (нет отражения во время выполнения), поэтому выполнение выполняется очень быстро.
РЕДАКТИРОВАТЬ: Ну, до сих пор SBQL4J это единственное расширение языка Java, который предоставляет возможности запросов, аналогичные LINQ. Есть несколько интересных проектов, таких как Quaere и JaQue, но они являются только API, а не расширением синтаксиса / семантики с высокой степенью безопасности типов во время компиляции.
Java LINQ to 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);
Вы можете попробовать мою библиотеку CollectionsQuery . Это позволяет запускать 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.persistence.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 to Objects) Java 8 будет иметь нечто эквивалентное, см. Project Lambda .
Он имеет расширения LINQ to Objects Enumerable, такие как вещи . Но для более сложных вещей LINQ, таких как Expression и ExpressionTree (они необходимы для LINQ to SQL и других провайдеров LINQ, если они хотят предоставить что-то оптимизированное и реальное), эквивалента пока нет, но, возможно, мы увидим это в будущем :)
Но я не думаю, что в будущем будет что-то вроде декларативных запросов на Java.
Там нет такой функции в Java. Используя другой API, вы получите эту функцию. Например, предположим, что у нас есть животный объект, содержащий имя и идентификатор. У нас есть список объектов с животными. Теперь, если мы хотим получить имя животного, которое содержит 'o', из объекта списка. мы можем написать следующий запрос
from(animals).where("getName", contains("o")).all();
Выше заявления Query будет список животных, которые содержат алфавит «о» в их названии. Более подробную информацию можно найти в следующем блоге. http://javaworldwide.blogspot.in/2012/09/linq-in-java.html
Проверьте крошечный вопрос . (Обратите внимание, что в настоящее время вы не можете скачать его.)
Вот пример адаптированной вышеуказанной ссылки:
Сначала нам нужен набор некоторых данных, скажем, набор строк
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 предоставляет базовый класс Enumerable, который содержит отложенные цепочечные методы для реализации запроса к коллекции или массиву.
Поддерживаемые методы: любой, приведение, контакт, содержит, считать, отличить, elementAt, кроме, first, firstOrDefault, groupBy, interset, join, last, lastOrDefault, ofType, orderBy, orderByDescending, обратный, select, selectMany, single, singleOrDefault, пропустить , skipWhile, take, takeWhile, toArray, toArrayList, union, где
Scala.Now я прочитал это, и нашел это как linq, но более простой и более нечитаемый. но Scala может работать в Linux, да? Csharp нужно моно.
Был язык программирования Pizza (расширение Java), и вы должны взглянуть на него. - Он использует концепцию «плавных интерфейсов» для запроса данных декларативным образом, и это в принципе идентично LINQ без выражений запросов (http://en.wikipedia.org/wiki/Pizza_programming_language). Но, увы, это не преследовалось, но это был бы один из способов получить что-то похожее на LINQ в Java.
Нет эквивалента LINQ для Java. Но есть некоторые внешние API, которые похожи на LINQ, такие как https://github.com/nicholas22/jpropel-light , https://code.google.com/p/jaque/
Вы можете попробовать эту библиотеку: https://code.google.com/p/qood/
Вот несколько причин, чтобы использовать его: