0

I am having trouble with my code to add iterator support to ArrayList this is the class i create to implement Iterator

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++];
}

} This must include, which i think i did correct

"list" of type MyArrayList
"currentIndex" of type int, initially at zero

This is my main method for testing

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);
        }
}

}

In the myArrayList i have added as the requirement is Make MyArrayList implement the Iterable interface by adding the iterator() method, which should return an instance of MyArrayListIterator.

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

Please let me know what I am doing wrong.

nrw2631
  • 11
  • 2
  • Where's your `next()` implementation? – Slaw Sep 23 '21 at 01:55
  • Does MyList extend Iterable? – the Hutt Sep 23 '21 at 01:58
  • I have added next() and it did not extend Iterable – nrw2631 Sep 23 '21 at 02:02
  • You never seem to initialize `list` to a non-`null` value, so I assume you're getting a `NullPointerException`. If that's not the case then please clarify how your code is not working. – Slaw Sep 23 '21 at 02:03
  • extending Iterable removed all errors but once i ran the code I received Cannot read the array length because "this.list" is null – nrw2631 Sep 23 '21 at 02:04
  • Yes, that's a `NullPointerException`. This likely makes your question a duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it). – Slaw Sep 23 '21 at 02:07
  • how do i fix this? i read the link provided but it's still not clear – nrw2631 Sep 23 '21 at 02:31
  • Create a parameter to the constructor for `MyArrayListIterator` and use that to initialize the `list` field. – Stephen C Sep 23 '21 at 10:22
  • You're trying to iterate something, presumably the array in your `MyArrayList` class. Inside the `MyArrayListIterator` you never initialize `list` to anything. So I would assume the fix is to initialize `list` to the same instance as, or a copy of, the "list" in the outer class. – Slaw Sep 23 '21 at 18:55

1 Answers1

0

As already mentioned in the comments, your problem is that you read from list in MyArrayListIterator without initializing it. This causes a NullPointerException.

You can fix this in two different ways:

  1. Make MyArrayListIterator a non-static nested (they are also called inner classes) class of MyArrayList.

    By doing so, you get access to all fields of the outer-class, which in this case is MyArrayList. For example, see this code snippet:

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. Make MyArrayListIterator a static nested class or a separate class.

    In this case, you don't have access to the fields defined in MyArrayList, which means you have to provide them yourself. This can be done using the constructor.

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++];
    }
  }
}

For more information on nested classes, see this tutorial by Oracle on nested classes.

Michi
  • 26
  • 4