Eu sei que não há equivalente direto no próprio Java, mas talvez um terceiro?
É muito conveniente. Atualmente, gostaria de implementar um iterador que produza todos os nós em uma árvore, que tem cerca de cinco linhas de código com rendimento.
java
yield
yield-return
ripper234
fonte
fonte
Respostas:
As duas opções que conheço são a biblioteca infomancers-collection de Aviad Ben Dov de 2007 e a biblioteca YieldAdapter de Jim Blackler de 2008 (que também é mencionada na outra resposta).
Ambos permitirão que você escreva código com a
yield return
construção -like em Java, então ambos irão satisfazer sua solicitação. As diferenças notáveis entre os dois são:Mecânica
A biblioteca do Aviad está usando manipulação de bytecode, enquanto a do Jim usa multithreading. Dependendo de suas necessidades, cada um pode ter suas próprias vantagens e desvantagens. É provável que a solução do Aviad seja mais rápida, enquanto a do Jim é mais portátil (por exemplo, não acho que a biblioteca do Aviad funcione no Android).
Interface
A biblioteca do Aviad tem uma interface mais limpa - aqui está um exemplo:
Enquanto Jim's é muito mais complicado, exigindo
adept
um genéricoCollector
que tem umcollect(ResultHandler)
método ... ugh. No entanto, você pode usar algo como este wrapper em torno do código de Jim por Zoom Information, que simplifica muito isso:Licença
A solução da Aviad é BSD.
A solução de Jim é de domínio público, assim como seu invólucro mencionado acima.
fonte
AbstractIterator
.yield(i)
será interrompido a partir do JDK 13, já queyield
está sendo adicionado como uma nova instrução Java / palavra-chave reservada.Ambas as abordagens podem ser um pouco mais claras agora que o Java tem Lambdas. Você pode fazer algo como
Eu expliquei um pouco mais aqui.
fonte
Yielderable
? Não deveria serYieldable
? (o verbo sendo apenas 'render', não 'yielder' ou 'yielderate' ou qualquer outro)yield -> { ... }
será interrompido a partir do JDK 13, poisyield
está sendo adicionado como uma nova instrução Java / palavra-chave reservada.Eu sei que é uma questão muito antiga aqui, e existem duas maneiras descritas acima:
yield
que obviamente tem custos de recursos.No entanto, existe outra maneira, a terceira e provavelmente a mais natural, de implementar o
yield
gerador em Java que é a implementação mais próxima do que os compiladores C # 2.0+ fazem parayield return/break
geração: lombok-pg . É totalmente baseado em uma máquina de estado e requer estreita cooperação com ajavac
para manipular o código-fonte AST. Infelizmente, o suporte lombok-pg parece ter sido descontinuado (sem atividade de repositório por mais de um ano ou dois), e o Projeto Lombok original infelizmente não tem oyield
recurso (ele tem um IDE melhor como Eclipse, suporte IntelliJ IDEA, entretanto).fonte
Stream.iterate (seed, seedOperator) .limit (n) .foreach (action) não é o mesmo que operador de rendimento, mas pode ser útil escrever seus próprios geradores desta maneira:
fonte
Eu também sugiro se você já estiver usando RXJava em seu projeto, use um Observable como um "rendimento". Ele pode ser usado de maneira semelhante se você fizer seu próprio Observável.
Os observáveis podem ser transformados em iteradores para que você possa até mesmo usá-los em loops for mais tradicionais. Além disso, RXJava oferece ferramentas realmente poderosas, mas se você só precisa de algo simples, talvez isso seja um exagero.
fonte
Acabei de publicar outra solução (licenciada pelo MIT) aqui , que inicia o produtor em um thread separado e configura uma fila limitada entre o produtor e o consumidor, permitindo buffer, controle de fluxo e pipelining paralelo entre produtor e consumidor (então que o consumidor pode estar trabalhando no consumo do item anterior enquanto o produtor está trabalhando na produção do próximo item).
Você pode usar este formulário de classe interna anônimo:
por exemplo:
Ou você pode usar a notação lambda para reduzir o clichê:
fonte