我有以下Python生成器:
def iterator(min,max,step,min2,max2,step2):
for x in range(min,max,step):
for y in range(min2, max2, step2):
result = foo(x, y)
yield result
而且我想在Java中实现一个迭代器
,它的行为有点像之前的生成器。我曾尝试使用两个内部迭代器,但它不起作用。
我该怎么修?
public class Generator implements Iterator<Integer> {
private Iterator<Integer> xIterator;
private Iterator<Integer> yIterator;
public Generator(int max1, int max2, int min1, int min2, int step1, int step2) {
xIterator = range(min1, max1, step1).iterator();
yIterator = range(min2, max2, step2).iterator();
}
@Override
public Integer next() {
while (xIterator.hasNext()) {
xval = xIterator.next()
while(yIterator.hasNext()) {
yval = yIterator.next()
return foo(xval, yval)
}
}
}
public static int[] range(int min, int max, int step) {
return IntStream.range(min, max / step + 1).map(x -> x * step).toArray();
}
}
Java中的Iterator是一个特殊的对象,是迭代的平均值,它允许从特定的源按顺序一个接一个地检索元素。
创建自定义迭代器时必须实现两种方法:hasNext()
(如果存在下一个元素,则返回true
)和next()
(检索下一个元素)。
您没有为您的类提供hasNext()
的实现,否则您的代码将无法编译。
next()
方法中有一个逻辑缺陷,它将无法编译,因为您没有提供返回语句或抛出子句,当控件无法进入循环时,这些语句或子句将被执行。但更重要的是,在这个方法中不需要循环和任何条件逻辑,它必须被hasNext()
覆盖,通常必须在next()
之前调用。如果客户端代码不尊重它,方法next()
可能会产生异常。您可以在next()
方法的开头添加if(hasNext())
,以对自定义消息发出特定异常。
methoditerator()
可通过数组访问。您可以将其与实现Iterable
接口的类一起使用,例如集合,您还可以在流上调用iterator()
。因此,您可以像这样重新实现您的方法range()
:
IntStream.iterate(min, i -> i < max, i -> i + step).iterator();
这就是如何修复迭代器:
public class Generator implements Iterator<Integer> {
private final Iterator<Integer> xIterator;
private final Iterator<Integer> yIterator;
public Generator(int minX, int minY, int maxX, int maxY, int stepX, int stepY) {
this.xIterator = range(minX, maxX, stepX);
this.yIterator = range(minY, maxY, stepY);
}
public static Iterator<Integer> range(int min, int max, int step) {
return IntStream.iterate(min, i -> i < max, i -> i + step).iterator();
}
@Override
public boolean hasNext() {
return xIterator.hasNext() && yIterator.hasNext();
}
@Override
public Integer next() {
return foo(xIterator.next(), yIterator.next());
}
}
但是我的建议是更倾向于效率和简单而不是简洁。因为迭代器产生的所有值都可以很容易地动态计算,所以没有必要提前分配它们来占用内存。
相反,您可以维护两个变量curX
和curY
。这个解决方案很简单,而且可以对迭代器进行更多的控制,因为您没有委派迭代过程。因此,您可以实现一个reset()
功能(这是不可能的,因为以前的解决方案,Iterator
在到达数据源末尾时变得无用)。
public class Generator implements Iterator<Integer> {
private final int minX;
private final int minY;
private final int maxX;
private final int maxY;
private final int stepX;
private final int stepY;
private int curX;
private int curY;
public Generator(int minX, int minY, int maxX, int maxY, int stepX, int stepY) {
this.minX = minX;
this.minY = minY;
this.maxX = maxX;
this.maxY = maxY;
this.stepX = stepX;
this.stepY = stepY;
this.curX = minX;
this.curY = minY;
}
@Override
public boolean hasNext() {
return curX < maxX && curY < maxY;
}
@Override
public Integer next() {
int result = foo(curX, curY);
curX += stepX;
curY += stepY;
return result;
}
public void reset() { // reset the iterator to the initial coordinates
this.curX = minX;
this.curY = minY;
}
}
在Python中,在一条yield语句之后,对生成器的下一次调用将在该yield语句之后继续进行,该语句位于内部循环中。
在Java中,在返回之后,对next()的下一次调用将在while循环之外继续,因此它所做的第一件事总是检查xIterator。hasNext(),如果这是真的,则递增xval。我认为这可能是主要的误解。
而且,范围函数似乎没有完成它应该做的事情。也许可以看看Java:相当于Python的范围(int,int)?-其中一些答案还包括step论证。
您发布的代码也不会编译,原因如下:
我有以下python生成器: 而且我想在Java中实现一个迭代器,它的行为有点像以前的生成器。我试图使用两个内部迭代器,但它不起作用。想法?
问题内容: 我有一个像这样的嵌套循环构造: 现在如何摆脱两个循环?我看过类似的问题,但没有一个是Java特有的。我无法应用这些解决方案,因为大多数使用的gotos。 我不想将内部循环使用其他方法。 我不想重新运行循环。中断时,我完成了循环块的执行。 问题答案: 像其他答复者一样,我绝对希望将循环放入另一种方法中,此时你可以返回以完全停止迭代。该答案仅显示了如何满足问题中的要求。 你可以将break
为了在运行性能脚本之前用大量数据填充系统,我们理想的用例是使用Gatling。数据不需要不同,除了具有唯一的主ID。 上面的示例可以通过更改的值来创建任意数量的对象,但是在大范围(例如100000个对象)下,线性地这样做变得不切实际。所以我想做的是有一个共享的对象池,由100个用户创建。 当然,这就是喂食器的使用案例。而不是生成一个静态的或使用使用简单的迭代循环(例如到)似乎最简单。 我知道(从文
您认为这样的迭代器嵌套是好还是坏? 上下文:for循环版本中断,因为我在for循环中使用同义词的同时附加同义词。 或者,在for循环版本中,我可以复制HashMap 非常感谢。 下面是一个更好的例子。 目前正在考虑使用HashMap.size()用for循环替换第一个itr,这样当我稍后追加HashMap时就不会中断。 非常感谢。
问题内容: 考虑以下代码: 我有一些要求,例如我想读取/获取所有类型的键和值以进行某些处理,但我无法定义它,因为我将获得动态JSON输入(例如,作为字符串,那么第二级循环将给我索引)数组并处理每个具有key 和的JSON 。 我希望遍历其中包含的每个键/值对,浏览地图的最有效方法是什么? 注意:我是Go-lang的新手,也欢迎您提出问题。 问题答案: 请参阅此博客条目,该条目彻底涵盖了该主题,尤其
问题内容: 我已经使用Java已有一段时间了,但是我对循环的教育还是有点不足。我知道如何创建存在于Java中的每个循环以及如何打破循环。但是,最近我想到了: 假设我有两个嵌套循环。我可以只使用一条语句来打破两个循环吗? 这是我到目前为止所拥有的。 有没有办法做到这一点? 问题答案: 在Java中,您可以使用标签来指定要中断/继续的循环: