2

I have an assignment to complete a DoublyLinkList assignment and I am having some difficulty with two of the methods. I was given the code for MyList and MyAbstractList and was told to extend MyAbstractList with my DoublyLinkedList. I am not allowed to change MyList or MyAbstractList.

Here is the code for MyList I was provided:

   public interface MyList<E extends Comparable<E>>  {

      /** Return true if this list contains no elements */
      public boolean isEmpty();

      /** Return the number of elements in this list */
      public int size();

      /** Add a new element at the proper point */
      public void add(E e);

      /** Clear the list */
      public void clear();

      /** Return true if this list contains the element */
      public boolean contains(E e);

      /** Return the element from this list at the specified index */
      public E get(int index);

      /** Return the first element in the list */
      public E getFirst();

      /** Return the last element in the list */
      public E getLast();

      /** Return the index of the first matching element in this list.
       *  Return -1 if no match. */
      public int indexOf(E e);

      /** Return the index of the last matching element in this list
       *  Return -1 if no match. */
      public int lastIndexOf(E e);

      /** Remove the first occurrence of the element o from this list.
       *  Shift any subsequent elements to the left.
       *  Return true if the element is removed. */
      public boolean remove(E e);

      /** Remove the element at the specified position in this list
       *  Shift any subsequent elements to the left.
       *  Return the element that was removed from the list. */
      public boolean remove(int index);

      /** Remove the first element in the list, return true if done, false if list is empty */
      public boolean removeFirst();

      /** Remove the Last element in the list, return true if done, false if list is empty */
      public boolean removeLast();

      /** Replace the element at the specified position in this list
       *  with the specified element and return true if done, false if index out of range. */
      public boolean set(int index, E e);

    }

and this was the code I was provided for MyAbstractList:

public abstract class MyAbstractList<E extends Comparable<E>> implements MyList<E> {
  protected int size = 0; // The size of the list

  /** Create a default list */
  protected MyAbstractList() {
  }

  /** Create a list from an array of objects */
  public MyAbstractList(E[] objects) {
      for (int i = 0; i < objects.length; i++)
          add(objects[i]);
  }

 @Override /** Return true if this list contains no elements */
  public boolean isEmpty() {
    return size == 0;
  }

  @Override /** Return the number of elements in this list */
  public int size() {
    return size;
  }

}

Finally here is my code for MyDoublyLinkedList:

import java.util.ArrayList;
public class MyDoublyLinkedList<E extends Comparable<E>> extends MyAbstractList<E>
{
    int size =0;
    Node<E> head = null;
    Node<E> current = null;
    Node<E> tail = null;
    public MyDoublyLinkedList() {

    }

    /** Create a list from an array of objects */
    public MyDoublyLinkedList(E[] objects) {
        super(objects);
    }

    @Override
      public boolean isEmpty()
      {
        return size == 0;
      }

    @Override
      public int size()
      {
          return size;
        }
    /** Add a new element at the proper point */
    @Override
      public void add(E e)
      {
        Node<E> newNode = new Node<E>(e);
        if (tail == null) {
            head = tail = newNode;

        } 
        else //if (head != null)
        {
            tail.next = newNode;
            tail = newNode;

        }     

        size++;

    }

    @Override
      public void clear()
      {
          size = 0;
          head = tail = null;
        }

    @Override
      public boolean contains(E e)
      {
      Node<E> current = head;
      for (int i = 0; i < size; i++) {
        if (current.element.equals(e))
          return true;
        current = current.next;
      }

      return false;
        }

    @Override
      public E get(int index)
      {
      if (index < 0 || index > size - 1)
        return null;

      Node<E> current = head;
      for (int i = 0; i < index; i++)
        current = current.next;

      return current.element;
        }

    @Override
      public E getFirst()
      {
        if (size == 0) {
          return null;
        }
        else {
          return head.element;
        }
        }

    @Override
      public E getLast()
      {
        if (size == 0) {
          return null;
        }
        else {
          return tail.element;
        }
        }

    @Override
      public int indexOf(E e)
      {
          Node<E> current = head;
      for (int i = 0; i < size; i++) {
        if (current.element.equals(e))
          return i;
        current = current.next;
      }

      return -1;
        }

    @Override
      public int lastIndexOf(E e)
      {
      int lastIndex = -1;
      Node<E> current = head;
      for (int i = 0; i < size; i++) {
        if (current.element.equals(e))
          lastIndex = i;
        current = current.next;
      }

      return lastIndex;
        }
    /** Remove the first occurrence of the element o from this list.
    *  Shift any subsequent elements to the left.
    *  Return true if the element is removed. */
    @Override
      public boolean remove(E e)
      {
        int index = indexOf(e);
        if (index != -1) {
            return remove(index);
        } else {
            return false;
        }



        }
    /** Remove the element at the specified position in this list
    *  Shift any subsequent elements to the left.
    *  Return the element that was removed from the list. */
    @Override
      public boolean remove(int index)
      {
        if (index < 0 || index >= size) {
          return false;
        }
        else if (index == 0) {
          return removeFirst();
        }
        else if (index == size - 1) {
          return removeLast();
        }
        else {
          Node<E> previous = head;

          for (int i = 1; i < index; i++) {
            previous = previous.next;
          }

          Node<E> current = previous.next;
          previous.next = current.next;
          size--;
          return true;
        }
        }

    @Override
      public boolean removeFirst()
      {
          if (size == 0) {
          return false;
        }
        else {
          Node<E> temp = head;
          head = head.next;
          size--;
          if (head == null) {
            tail = null;
          }
          return true;
        }
        }

    @Override
      public boolean removeLast()
      {
       if (size == 0) {
              return false;
        }
        else if (size == 1) {
          Node<E> temp = head;
          head = tail = null;
          size = 0;
          return true;
        }
        else {
          Node<E> current = head;

          for (int i = 0; i < size - 2; i++) {
            current = current.next;
          }

          Node<E> temp = tail;
          tail = current;
          tail.next = null;
          size--;
          return true;
        }
    }
    @Override
      public boolean set(int index, E e)
      {
          if (index < 0 || index > size - 1)
            return false;

          Node<E> current = head;
          for (int i = 0; i < index; i++)
            current = current.next;

          E temp =  current.element;
          current.element = e;

          return true;
        }

    @Override
    public String toString()
    {
        StringBuilder result = new StringBuilder("[");

        Node<E> current = head;
        for (int i = 0; i < size; i++) {
          result.append(current.element);
          current = current.next;
          if (current != null) {
            result.append(", "); // Separate two elements with a comma
          }
          else {
            result.append("]"); // Insert the closing ] in the string
          }
        }

        return result.toString();
    }

        public String toStringBack()
    {
        StringBuilder result = new StringBuilder("[");

        Node<E> current = tail;
        for (int i = 0; i < size; i++) {
          result.append(current.element);
          current = current.previous;
          if (current != null) {
            result.append(", "); // Separate two elements with a comma
          }
          else {
            result.append("]"); // Insert the closing ] in the string
          }
        }

        return result.toString();
    }

    public void add(int index, E e)
    {

       if (index ==0) {
          addFirst(e);// The new node is the only node in list
        }
        else if(index > size)
        {
            addLast(e);//The index location was bigger than size
        }
        else
        {
            Node<E> current = getAtIndex(index-1);
            Node<E> temp = current.next;
            current.next = new Node<E>(e);
            (current.next).next = temp;
            size++;
       }

    }

    public void addFirst(E e)
    {
        Node<E> newNode = new Node<E>(e); // Create a new node
        newNode.next = head; // link the new node with the head
        head = newNode; // head points to the new node
        size++; // Increase list size

        if (tail == null) // the new node is the only node in list
          tail = head;

    }

    public void addLast(E e)
    {
        Node<E> newNode = new Node<E>(e); // Create a new for element e

        if (tail == null) {
          head = tail = newNode; // The new node is the only node in list
        }
        else {
          tail.next = newNode; // Link the new with the last node
          tail = tail.next; // tail now points to the last node
        }

        size++;
    }

    protected Node<E> getAtIndex(int index)
    {
         int count;
         if (index < 0 || index > size - 1)
         return null;
         Node<E> temp = null;
         if(index <= (size/2))
           {
            count = -1;
            temp = head;
            while(++count <= index){
                temp = temp.next;
              }
          }
          else if (index > (size/2))
          {
            count = size;
            temp = tail;
            while(--count >= index){
                temp = temp.previous; //--> this is Where the null pointer exception occurs 
            }
        }
          return temp;
    }
    private static class Node<E>{
        E element;
        Node<E> next;
        Node<E> previous;
        public Node(E element){
            this.element = element;
            next = null;
            previous = null;
        }
      }
 }

When I run the add(int index, E e) Method I receive a null pointer exception in the getAtIndext() method. I also have had issues getting the add(E e) Method to add properly when I change the current location. The methods are all as I am being required to use them. The use of iterators while they would be nice are not allowed. I am using Bluj as a compiler. Please let me know what questions you have.

Thank you

EDIT: I do know what a Null Pointer Exception is, I can not figure out why this is coming back as null. The Node "current" should point to the end, then go back in the list until it reaches the indexed location. This only happens when I try to add a node in the last half of the list. The error is thrown at temp = temp.previous; The stack trace is: java.lang.NullPointerException at MyDoublyLinkedList.getAtIndex(MyDoublyLinkedList.java:345) at MyDoublyLinkedList.add(MyDoublyLinkedList.java:289) at TestMyDoublyLinkedList.main(TestMyDoublyLinkedList.java:50)

Edit: I figured out the issue. The add() and getAtIndex functions are running properly. When I run the test the function that is throwing a Null Pointer Exception is throwing it at position 8. It cycles through the first few nodes fine, but dies at node 8

  • 2
    Possible duplicate of [What is a NullPointerException, and how do I fix it?](http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – DimaSan Oct 28 '16 at 10:27
  • Could you add a stack trace please? That will help alot – Viorel Florian Oct 28 '16 at 10:55

1 Answers1

0

When inserting in the add() method, you never assign previous so it is null for all nodes.

eduyayo
  • 2,020
  • 2
  • 15
  • 35
  • But that doesn't explain why the .next would work. These are defined in class Node, and the section above the one throwing a Null pointer has .next which I also did not define in the getAtIndex method. – BlankKitOkami Oct 30 '16 at 10:30
  • When inserting you just assign next but not previous. – eduyayo Oct 30 '16 at 12:19