Wiem, że w samej Javie nie ma bezpośredniego odpowiednika, ale być może strona trzecia?
To naprawdę wygodne. Obecnie chciałbym zaimplementować iterator, który zwraca wszystkie węzły w drzewie, czyli około pięciu wierszy kodu z wydajnością.
java
yield
yield-return
zrywak234
źródło
źródło
Odpowiedzi:
Dwie opcje znam to Aviad Ben Dov za infomancers-zbiory biblioteki od 2007 i Jim Blackler za YieldAdapter biblioteka z 2008 roku (który jest również wymienione w drugiej odpowiedzi).
Oba pozwolą ci pisać kod z
yield return
konstrukcją podobną do typu w Javie, więc oba spełnią twoje żądanie. Istotne różnice między nimi to:Mechanika
Biblioteka Aviad używa manipulacji kodem bajtowym, podczas gdy Jim używa wielowątkowości. W zależności od potrzeb każdy może mieć swoje zalety i wady. Prawdopodobnie rozwiązanie Aviad jest szybsze, podczas gdy Jim jest bardziej przenośny (na przykład nie sądzę, aby biblioteka Aviad działała na Androidzie).
Berło
Biblioteka Aviad ma bardziej przejrzysty interfejs - oto przykład:
Podczas gdy Jim jest o wiele bardziej skomplikowany, wymaga od ciebie
adept
generycznego,Collector
który macollect(ResultHandler)
metodę ... ugh. Możesz jednak użyć czegoś takiego jak ta otoka wokół kodu Jima autorstwa Zoom Information, co znacznie upraszcza to:Licencja
Rozwiązaniem Aviad jest BSD.
Rozwiązanie Jima jest własnością publiczną, podobnie jak jego opakowanie, o którym wspomniano powyżej.
źródło
AbstractIterator
.yield(i)
zepsuje się od JDK 13, ponieważyield
jest dodawany jako nowa instrukcja Java / zastrzeżone słowo kluczowe.Oba te podejścia można uczynić nieco czystszymi, teraz Java ma Lambdy. Możesz zrobić coś takiego
Trochę więcej wyjaśniłem tutaj.
źródło
Yielderable
? Czy nie powinno tak byćYieldable
? (czasownik to po prostu „ustąpić”, a nie „ustąpić”, „ustąpić” czy cokolwiek)yield -> { ... }
zepsuje się od JDK 13, ponieważyield
jest dodawany jako nowa instrukcja Java / zastrzeżone słowo kluczowe.Wiem, że to bardzo stare pytanie i są dwa sposoby opisane powyżej:
yield
które oczywiście wiążą się z kosztami zasobów.Istnieje jednak inny, trzeci i prawdopodobnie najbardziej naturalny sposób implementacji
yield
generatora w Javie, który jest najbliższą implementacją do tego, co kompilatory C # 2.0+ robią dlayield return/break
generacji: lombok-pg . Jest w pełni oparty na automacie stanowym i wymaga ścisłej współpracy zjavac
kodem źródłowym AST. Niestety, wydaje się, że obsługa lombok-pg została przerwana (brak aktywności repozytorium przez ponad rok lub dwa), a oryginalny Project Lombok niestety nie ma tejyield
funkcji (ma lepsze IDE, takie jak Eclipse, wsparcie IntelliJ IDEA).źródło
Stream.iterate (seed, seedOperator) .limit (n) .foreach (akcja) to nie to samo, co operator yield, ale może być przydatne napisanie własnych generatorów w ten sposób:
źródło
Sugerowałbym również, jeśli już używasz RXJava w swoim projekcie, aby użyć Observable jako „yieldera”. Można go użyć w podobny sposób, jeśli stworzysz własny Observable.
Observables można przekształcić w iteratory, dzięki czemu można ich używać nawet w bardziej tradycyjnych pętlach for. Również RXJava zapewnia naprawdę potężne narzędzia, ale jeśli potrzebujesz tylko czegoś prostego, może to byłaby przesada.
źródło
Właśnie opublikowano kolejną (MIT licencjonowanych) roztworu tutaj , otwiera się do producenta w oddzielnym wątku oraz określa ograniczonym kolejki pomiędzy producenta i konsumenta, dzięki czemu do buforowania, do kontroli przepływu i równoległe przetwarzanie potokowe od producenta i konsumenta (tak że konsument może pracować nad skonsumowaniem poprzedniego przedmiotu, podczas gdy producent pracuje nad wyprodukowaniem następnego).
Możesz użyć tego anonimowego formularza klasy wewnętrznej:
na przykład:
Lub możesz użyć notacji lambda, aby zmniejszyć wartość domyślną:
źródło