【问题标题】:How to implement an iterator?如何实现迭代器?
【发布时间】:2016-01-23 10:54:18
【问题描述】:

我的课程有问题,我无法解决。我想为我的Interval1 类实现一个迭代器。这是我的代码:

public class Interval1 {
    private double first;
    private double last;
    private double step;
    private IntervalIterator e;

    public Interval1(double first, double last, double step,  IntervalIterator e) {
        //chequear los datos
        this.first = first;
        this.last = last;
        this.step = step;
        this.e = new IntervalIterator();
    }

    public  double at(int index) {
        checkIndex(index);
        return first + index*step;
    }

    private void checkIndex(int index) {
        if(index < 0 || index >= size())
            throw new IndexOutOfBoundsException("Invalid Index: " + index);
    }

    public int size() {
        return (int) ((last - first) / step);
    }

    public IntervalIterator e() {
        for (Double i : this)
            System.out.println(i);
        return e;
    }
}

这是我正在使用的 IntervalIterator 类,这会在 size()at 中给出错误:

public class IntervalIterator implements Iterator<Double> {
    private int index = 0;
    private Double at;

    public boolean hasNext() {
        return index < size();
    }

    public Double next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }
        return at(index++);
    }

    public void remove() {
        if (Interval1 <= 0) {
            return throw new UnsupportedOperationException("remove");
        } else {
            if (Interval1 >= 0) {
                //chekear el array e eliminarlo
            }
        }
    }
}

【问题讨论】:

  • 开始格式化您的代码,使其可读。
  • hasNext(),您希望代码调用哪个size() 方法?字段at 用于什么?在next() 中,您希望该代码调用哪个at() 方法?在remove() 中,变量/字段/参数Interval1 定义在哪里?
  • Interval1构造函数中,参数e是干什么用的?一个迭代器只能使用一次,所以第二次调用e()(奇怪的名字)将返回已经用尽的迭代器。在e()中,this不是一个可迭代对象,for不能在for这样的循环中使用。
  • 对于第一个/最后一个/步骤值 3/9/2 我希望值 3,5,7,9 返回,但 size() 返回 @ 987654345@,不是4

标签: java arrays list iterator


【解决方案1】:

我会使用 java8 流返回 Iterator&lt;Double&gt;:

public class Interval
    implements Iterable<Double> {

    private final double first;
    private final double last;
    private final double step;
    private final long size;

    public Interval(double first, double last, double step) {
        this.first = first;
        this.last = last;
        this.step = step;
        this.size = (long) ((last - first) / step) + 1;
    }

    @Override
    public Iterator<Double> iterator() {
        return DoubleStream.iterate(this.first, n -> n + this.step)
            .limit(this.size)
            .iterator();
    }

    // TODO getters
}

我在字段中添加了final 修饰符,并使Interval 类实现Iterable&lt;Double&gt;,以便可以对其进行迭代。我还修正了 size 的计算(需要加一)。

我使用了DoubleStream.iterate() method,它接收种子和接收流的当前元素作为输入并返回以下元素的函数(为此,我已将step 添加到当前元素) .我还必须使用DoubleStream.limit() method,因为DoubleStream.iterate() 生成的流是无限的。

用法:

Interval interval = new Interval(3.0, 9.0, 1.5);

for (double n : interval) {
    System.out.println(n);
}

以上代码生成如下输出:

3.0
4.5
6.0
7.5
9.0

【讨论】:

    猜你喜欢
    • 2020-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-09
    • 1970-01-01
    • 2013-06-30
    相关资源
    最近更新 更多