为算术级数制作一个惰性迭代器?
下面是我编写的一个类,它为算术级数实现了 Iterablestart
到 stop
,步骤为 step
code>)
package com.example.test;
import java.util.Iterator;
import com.google.common.collect.AbstractIterator;
public class ArithmeticSeries implements Iterable<Integer>
{
final private int start, step, stop;
public int getStart() { return this.start; }
public int getStep() { return this.step; }
public int getStop() { return this.stop; }
public ArithmeticSeries(int start, int step, int stop)
{
this.start = start;
this.step = step;
this.stop = stop;
}
@Override public Iterator<Integer> iterator()
{
return new AbstractIterator<Integer>() {
private Integer n = null;
@Override protected Integer computeNext() {
int next;
if (this.n == null)
{
next = getStart();
}
else
{
next = this.n + getStep();
if ((getStep() > 0 && next > getStop())
|| (getStep() < 0 && next < getStop()))
return endOfData();
}
this.n = next;
return next;
}
};
}
@Override public String toString() {
return getStart()+":"+getStep()+":"+getStop();
}
public static void main(String[] args) {
Iterable<Integer> range = new ArithmeticSeries(100,-1,80);
System.out.println(range);
for (int i : range)
System.out.println(i);
}
}
有没有一种更优雅的实现 iterator()
的方法?我不喜欢空检查和使用Integer
(替代方案是一个额外的标志boolean firstTime
),这似乎是错误的。
Here's a class I wrote that implements Iterable<Integer>
for an arithmetic series (from start
to stop
in steps of step
)
package com.example.test;
import java.util.Iterator;
import com.google.common.collect.AbstractIterator;
public class ArithmeticSeries implements Iterable<Integer>
{
final private int start, step, stop;
public int getStart() { return this.start; }
public int getStep() { return this.step; }
public int getStop() { return this.stop; }
public ArithmeticSeries(int start, int step, int stop)
{
this.start = start;
this.step = step;
this.stop = stop;
}
@Override public Iterator<Integer> iterator()
{
return new AbstractIterator<Integer>() {
private Integer n = null;
@Override protected Integer computeNext() {
int next;
if (this.n == null)
{
next = getStart();
}
else
{
next = this.n + getStep();
if ((getStep() > 0 && next > getStop())
|| (getStep() < 0 && next < getStop()))
return endOfData();
}
this.n = next;
return next;
}
};
}
@Override public String toString() {
return getStart()+":"+getStep()+":"+getStop();
}
public static void main(String[] args) {
Iterable<Integer> range = new ArithmeticSeries(100,-1,80);
System.out.println(range);
for (int i : range)
System.out.println(i);
}
}
Is there a way to implement iterator()
that's more elegant? I don't like the null check and use of Integer
(alternative would be an extra flag boolean firstTime
), it just seems wrong.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您愿意,您可以将其实现为不可变的
List
。如果您扩展AbstractList
那么Iterator
将会为您处理。实际上,我认为AbstractList
确实是最好的方法。整个类看起来像这样(我没有检查它是否在所有情况下都能正常工作):If you wanted to, you could probably implement this as an immutable
List<Integer>
. If you extendAbstractList
then theIterator
would be taken care of for you. Actually, I thinkAbstractList
would really be the best way to go. The whole class would look like something like this (I haven't checked that it works right in all situations):您可以使用函数来抽象连续值,并使用谓词来控制迭代的结束,最终创建一个 Unfold 实现:
然后 ArithmeticSeries 变为:
当然,代码现在看起来更复杂,但是使用适当的用于比较和代数的基本函数,调用变得更加清晰:
You can use a Function to abstract the successive values and a Predicate to control the end of iteration, eventually creating an Unfold implementation:
Then ArithmeticSeries becomes:
Of course the code seems more complex now, but with appropriate base functions for comparison and algebra the call becomes much clearer:
我认为解决番石榴问题的最佳工具是 AbstractLinkedIterator。您的示例的实现如下所示:
您可以轻松地为此迭代器创建一个
Iterable
适配器,例如:但是,这种方法对返回
null
的提供函数做出了特殊约束。I think the best tool for your problem in guava is the
AbstractLinkedIterator
. Implementation of your example would look like this:You can easily create an
Iterable
adapter for this iterator, e.g. like this:However this approach makes special constraints on the provided function returning
null
.