Я знаю, что в самой Java нет прямого эквивалента, но, возможно, стороннего производителя?
Это действительно удобно. В настоящее время я хотел бы реализовать итератор, который выдает все узлы в дереве, что составляет около пяти строк кода с yield.
java
yield
yield-return
ripper234
источник
источник
Ответы:
Два варианта, о которых я знаю, - это библиотека infomancers-collection Aviad Ben Dov с 2007 года и библиотека YieldAdapter Джима Блэклера с 2008 года (которая также упоминается в другом ответе).
Оба позволят вам написать код с
yield return
конструкцией -like на Java, поэтому оба будут удовлетворять ваш запрос. Заметные различия между ними:механика
Библиотека Aviad использует манипуляции с байт-кодом, а библиотека Джима использует многопоточность. В зависимости от ваших потребностей у каждого могут быть свои преимущества и недостатки. Вероятно, решение Aviad быстрее, а решение Джима более портативно (например, я не думаю, что библиотека Aviad будет работать на Android).
Интерфейс
Библиотека Aviad имеет более чистый интерфейс - вот пример:
В то время как у Джима намного сложнее, требуя от вас
adept
общего, уCollector
которого естьcollect(ResultHandler)
метод ... тьфу. Однако вы можете использовать что-то вроде этой оболочки вокруг кода Джима от Zoom Information, что значительно упрощает это:Лицензия
Решение Aviad - BSD.
Решение Джима является общественным достоянием, как и его оболочка, упомянутая выше.
источник
AbstractIterator
.yield(i)
с JDK 13 это не работает, такyield
как добавляется как новый оператор Java / зарезервированное ключевое слово.Оба этих подхода можно сделать немного чище, теперь в Java есть Lambdas. Вы можете сделать что-то вроде
Я объяснил немного больше здесь.
источник
Yielderable
? Разве это не должно быть просто такYieldable
? (глагол просто «уступать», а не «уступать» или «уступать» или что-то еще)yield -> { ... }
не будет работать с JDK 13, посколькуyield
добавляется как новый оператор Java / зарезервированное ключевое слово.Я знаю, что это очень старый вопрос, и есть два описанных выше способа:
yield
что, очевидно, требует затрат ресурсов.Однако есть другой, третий и, вероятно, наиболее естественный способ реализации
yield
генератора на Java, наиболее близкий к тому, что компиляторы C # 2.0+ делают дляyield return/break
генерации: lombok-pg . Он полностью основан на конечном автомате и требует тесного взаимодействия сjavac
AST с исходным кодом. К сожалению, поддержка lombok-pg, похоже, прекращена (репозиторий не работает более года или двух), а в исходном Project Lombok, к сожалению, отсутствует этаyield
функция (у него лучшая IDE, такая как Eclipse, хотя поддержка IntelliJ IDEA).источник
Stream.iterate (seed, seedOperator) .limit (n) .foreach (action) - это не то же самое, что оператор yield, но может быть полезно написать свои собственные генераторы следующим образом:
источник
Я бы также посоветовал, если вы уже используете RXJava в своем проекте, использовать Observable в качестве «уступчика». Его можно использовать аналогичным образом, если вы создадите свой собственный Observable.
Наблюдаемые объекты можно преобразовать в итераторы, чтобы их можно было использовать даже в более традиционных циклах for. Также RXJava дает вам действительно мощные инструменты, но если вам нужно только что-то простое, возможно, это будет излишним.
источник
Я только что опубликовал еще одно решение (MIT лицензией) здесь , который запускает производитель в отдельном потоке, и устанавливает ограниченную очередь между производителем и потребителем, что позволяет буферизацию, управлению потоком и параллельно конвейерного между производителем и потребителем (так что потребитель может работать над потреблением предыдущего товара, в то время как производитель работает над производством следующего товара).
Вы можете использовать эту анонимную форму внутреннего класса:
например:
Или вы можете использовать лямбда-нотацию, чтобы сократить шаблон:
источник