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.

9
  • Where's your next() implementation? Commented Sep 23, 2021 at 1:55
  • Does MyList extend Iterable? Commented Sep 23, 2021 at 1:58
  • I have added next() and it did not extend Iterable Commented Sep 23, 2021 at 2: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. Commented Sep 23, 2021 at 2:03
  • extending Iterable removed all errors but once i ran the code I received Cannot read the array length because "this.list" is null Commented Sep 23, 2021 at 2:04

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.