TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Ask HN: What problems do Generators solve in Java?

3 点作者 redditor98654将近 2 年前
There has been some discussions lately about the need to support generators now that Virtual threads are a thing. I am reading up some examples and I still don&#x27;t understand what is a generator and why is it powerful.<p>Some examples from Python: https:&#x2F;&#x2F;www.programiz.com&#x2F;python-programming&#x2F;generator<p>Some examples using plain Java 8: https:&#x2F;&#x2F;www.mguenther.net&#x2F;2016&#x2F;01&#x2F;functional_generators_in_java_8&#x2F;index.html<p>I am a little confused why this is regarded as a powerful pattern. It seems I can implement the same using a normal `Iterator`. For instance, from the Python example:<p><pre><code> class PowTwoGen { final int max; int n = 0; PowTwoGen(int max) { this.max = max;} boolean hasNext() { return n &lt;= max;} int next() { return Math.pow(2, n++); } } </code></pre> The examples for the Java 8 article can also be done with a simple method call but instead the examples with the Generator seems overly complex. What am I missing?

3 条评论

PaulHoule将近 2 年前
I think that guy just made up a generator class for fun. It’s not too different from the interator except it doesn’t have a hasNext() method so it either returns results forever or it has to return a sentinel value like <i>null</i> or return an exception to end iteration.<p>Somebody could make the case that returning a sentinel value or an exception is a better API since there is no risk somebody else is going to call the next() method after you call hasNext() and next(). Writing a generator that wraps a generator is a little simpler than writing an interest or that wraps an iteration because you don’t have to write a hasNext() function, which can occasionally be awkward.<p>That generator library has a few functions, like <i>map</i> that work on generators, unfortunately the Java stdlib doesn’t come with anything like that. (There is the streams API but it is over-complicated.)<p>I’ll point out this library I wrote<p><a href="https:&#x2F;&#x2F;github.com&#x2F;paulhoule&#x2F;pidove">https:&#x2F;&#x2F;github.com&#x2F;paulhoule&#x2F;pidove</a><p>which does a lot of what the Steams library does but it works on iterators without creating streams. If you like those generator examples you might like pidove.<p>As for Python it is kinda accidental that generators would up related to coroutines, that is, generators were an easy way to implement coroutines, later async&#x2F;await and stuff like that got added.
armchairhacker将近 2 年前
A generator function can always be implemented via an iterator class, but often the generator is more convenient. Without generators, you manually need to convert loops and conditionals (typical programming) into an explicit state machine (atypical programming, and more verbose)<p>Your example in Python:<p><pre><code> class Pow2: def __init__(self, n): self.value = 0 self.n = n def __iter__(self): return self def __next__(self): if self.value &lt; self.n: ans = self.value * self.value self.value += 1 return ans else: raise StopIteration iter(Pow2(n)) </code></pre> is semantically equivalent to<p><pre><code> def pow2(n): value = 0 while value &lt; n: yield value * value value += 1 pow2(n) </code></pre> and<p><pre><code> (i * i for i in range(n)) </code></pre> but both the generators are a lot less code.<p>The generator expression (last one) can actually be implemented right now in Java streams (something like `IntRange::to(n).map(i =&gt; i * i)`). But the generator functions which use `yield` are necessary for more complex expressions: the ones which have nested loops, resources, exceptions, etc. which are even more verbose when converted into generator classes
cratermoon将近 2 年前
&gt; I am a little confused why this is regarded as a powerful pattern<p>The power of the generator is that, unlike an iterator, the collection of values doesn&#x27;t &quot;exist&quot;, it is created on the fly. This comes in to play when iterating over, say the set of integers, or something else that would take significant amounts of memory.<p>Also, as functions, generators can be passed around in any language that treats functions a first-class types.
评论 #36596206 未加载