帮助自定义迭代器

时间:2011-06-16 00:37:50

标签: java

我的自定义迭代器出现问题......似乎next()方法无效。

我认为我的构造函数不起作用...我收到此错误消息:java.lang.ArithmeticException:/ by zero

import java.util.Iterator;

public class RandomBag <Item> implements Iterable<Item>
{
  private Node first;
  private int N;
  private int k=0;

  private class Node
  {
    Item item;
    Node next;
  }

  public void add(Item item)
  {
    Node oldfirst = first;
    first = new Node();
    first.item = item;
    first.next = oldfirst;
    N++;
  }

  public boolean isEmpty()
  {
    return first == null;
  }

  public int size()
  {
    return N;
  }

  public Iterator<Item> iterator()
  {
    return new RandomIterator();
  }

  private class RandomIterator implements Iterator<Item>
  {    
    Item[] a = (Item[]) new Object [N];

    public RandomIterator()
    {
      int counter = 0;

      //put items in the array
      for (Node x=first; x!=null; x=x.next)
      {
        a[counter] = x.item;
        counter++;
      }

      //randomize the items in the array
      for (int i=0; i<size(); i++)
      {
        int randomIndex = StdRandom.uniform(i, size());
        Item item = a[randomIndex];
        a[randomIndex] = a[i];
        a[i] = item;
      }
    }

    public void remove() {}

    public boolean hasNext()
    {
      return k!=N;
    }

    public Item next()
    {
      Item item = a[k % a.length];
      k++;
      return item;
    }
  }
  public static void main(String[] args)
  {
    RandomBag<Double> numbers = new RandomBag<Double>();
    Iterator iter = numbers.iterator();

    numbers.add(1.0);
    numbers.add(4.0);
    numbers.add(3.0);
    numbers.add(5.0);

    StdOut.println(iter.next());
    StdOut.println(iter.next());
    StdOut.println(iter.next());
    StdOut.println(iter.next());
  }
}

3 个答案:

答案 0 :(得分:4)

问题出在这个方法中:

public Item next()
{
  Item item = a[k % a.length]; // If a.length is zero... BOOM
  k++;
  return item;
}

答案 1 :(得分:1)

首先:k变量应该是迭代器的一部分而不是类本身的一部分 - 否则只要你有超过1个迭代器就会得到明显无用的结果。

但问题是你为RandomBag类使用了一个参数less constructor,这意味着N被初始化为0.然后你用一个大小为N(= 0)的数组构造你的内部类迭代器并尝试使用它 - 这是行不通的。初始化Iterator后的add()方法完全没有效果 - 这使得这个迭代器相当无用(通常你应该在这里抛出并发修改异常并使用数据结构的数据而不是复制=)

PS:如果你想使用这个奇怪的迭代器,改变你的hasNext()方法来使用你的数组长度而不是N - 这将解决这个问题,因为next()不会被调用(或者如果它是,抛出一个例外很好)

答案 2 :(得分:1)

使用零长度包(或指出其他一些代码问题),它不会保护您免受此错误的影响,但移动此行:

Iterator iter = numbers.iterator();

在最终的。add()语句下面应该修复你正在看到的问题,因为迭代器正在numbers中的任何内容之前进行初始化。