Анализ и перевод выражений лямбда Java 8

В С# вы можете заключить лямбда-выражение в объект дерева выражений, а затем, возможно, проанализировать его. Мне было интересно, возможно ли это также на Java?

То, что я ищу, делает что-то вроде этого:

BooksRepository.getAll()
.where(b -> b.getIban() == "SomeIban")
.and(b -> b.getAuthor() == "SomeAuthor"); //etc.

И затем BooksRepository должен каким-то образом перевести этот запрос на следующий запрос API RESTful на основе предикатов, указанных как lambdas:

GET http://mylibrary.com/books?Iban=SomeIban&Author=SomeAuthor

а затем вернуть результат клиенту. Любая идея, если это возможно в Java?

Ответ 1

Да, это возможно. Я создал библиотеку, которая делает именно это: JaQue

Ответ 2

Я автор Jinq. Автоматические преобразования lambdas в деревья выражений, которые могут быть прочитаны во время выполнения, являются только функцией С#. Эта функция не имеет общего назначения для обычных программистов. Это в основном полезно только для реализации LINQ, поэтому разработчики языка не увлекались добавлением этой функции на Java или на другие языки. Были разговоры о добавлении какого-то фреймворка компилятора для Java, который позволит вам самостоятельно добавить функцию дерева выражений в Java, но я не слишком хорошо знаком с прогрессом в этом проекте.

Jinq содержит структуру анализа байт-кода, которая может строить простые деревья выражений из байт-кода lambda во время выполнения. Он основан на символическом исполнении и ASM. Его можно использовать для преобразования lambdas в деревья выражений, как и С#, но это довольно тяжелая процедура с большим количеством обручей, чтобы проскочить, так что это может быть излишним для того, что вы хотите сделать. Вы, по сути, будете обманывать муху молотком.

В JVM существуют языки, отличные от Java, которые лучше поддерживают метапрограммирование, которое вы хотите сделать. Поэтому вы также можете рассмотреть возможность поиска Groovy или Scala для этого.

Ответ 3

Что-то вроде Jinq?

database.customerStream().where(customer -> customer.getName().equals("Alice"));