【问题标题】:Implementing iterator to an ArrayList实现 ArrayList 的迭代器
【发布时间】:2021-11-16 10:40:38
【问题描述】:

我在向 ArrayList 添加迭代器支持时遇到问题 这是我为实现迭代器而创建的类

class MyArrayListIterator<E> implements Iterator<E> {
private E[] list = null;
private int currentIndex = 0;

@Override
public boolean hasNext() {
    if (currentIndex < list.length) {
        return true;
    } else {
        return false;
    }
}

@Override
public E next(){
    return list[currentIndex++];
}

} 这必须包括,我认为我做对了

MyArrayList 类型的“列表”
int 类型的“currentIndex”,初始为零

这是我的主要测试方法

public static void main(String[] args) throws Exception {
    MyList<String> names = new MyArrayList<>();
    
    names.add("Steve");
    names.add("Frank");
    names.add("Heather");
    names.add("Chris");
    names.add("Oliver");
    
      for (String string : names) {   // error at names Can only iterate over an array or an instance of java.lang.Iterable
            System.out.println(string);
        }
}

}

在我添加的 myArrayList 中,要求是通过添加 iterator() 方法使 MyArrayList 实现 Iterable 接口,该方法应返回 MyArrayListIterator 的实例。

public Iterator<E> iterator() {
    return new MyArrayListIterator();
}

请让我知道我做错了什么。

【问题讨论】:

  • 您的next() 实施在哪里?
  • MyList 是否扩展了 Iterable?
  • 我添加了 next() 并且它没有扩展 Iterable
  • 您似乎从未将list 初始化为非null 值,所以我假设您得到的是NullPointerException。如果不是这种情况,请说明您的代码是如何工作的。
  • 扩展 Iterable 删除了所有错误,但是一旦我运行收到的代码,我就无法读取数组长度,因为“this.list”为空

标签: java iterator


【解决方案1】:

正如 cmets 中已经提到的,您的问题是您从 list 中的 MyArrayListIterator 读取而没有初始化它。这会导致NullPointerException

您可以通过两种不同的方式解决此问题:

  1. MyArrayListIterator 设为non-static nested(它们也称为inner classes)类MyArrayList

    通过这样做,您可以访问外部类的所有字段,在本例中为 MyArrayList。比如看这段代码sn -p:

public class MyArrayList<E> implements MyList<E> {
  private Object[] list = new Object[10];
  private int size = 0;

  public Iterator<E> iterator(){
    return new MyArrayListIterator<>();
  }

  // more of your implementation...

  // This is the inner class
  private class MyArrayListIterator<T> implements Iterator<T> {
    private int currentIndex = 0;

    @Override
    public boolean hasNext() {
      // Since this is a inner class, we have access to the
      // "list" field defined by MyArrayList.
      return currentIndex < list.length;
    }

    @Override
    public T next() {
      // Since this is a inner class, we have access to the
      // "list" field defined by MyArrayList.
      return (T) list[currentIndex++];
    }
  }
}
  1. MyArrayListIterator 设为static nested 类或单独的类。

    在这种情况下,您无权访问MyArrayList 中定义的字段,这意味着您必须自己提供这些字段。这可以使用构造函数来完成。

public class MyArrayList<E> implements MyList<E> {
  private Object[] list = new Object[10];
  private int size = 0;

  public Iterator<E> iterator(){
    return new MyArrayListIterator<>((E[])list);
  }

  // More of your list implementation

  // This is a static inner class, which means we do not have access to
  // the fields of the outer class.
  private static class MyArrayListIterator<T> implements Iterator<T> {
    private final T[] elements;
    private int currentIndex = 0;

    public MyArrayListIterator(T[] elements) {
      this.elements = elements;
    }

    @Override
    public boolean hasNext() {
      // Since we got the elements as constructor argument, they are not
      // null (assuming you did not call it with null as parameter).
      return currentIndex < elements.length;
    }

    @Override
    public T next() {
      // Since we got the elements as constructor argument, they are not
      // null (assuming you did not call it with null as parameter).
      return elements[currentIndex++];
    }
  }
}

有关嵌套类的更多信息,请参阅this tutorial by Oracle 嵌套类。

【讨论】:

    猜你喜欢
    • 2016-08-23
    • 2020-11-09
    • 1970-01-01
    • 2023-02-03
    • 1970-01-01
    • 2018-10-06
    • 2016-01-23
    • 2012-01-22
    • 2018-03-14
    相关资源
    最近更新 更多