Home > Mobile >  Error when trying to add into doubly linked list Java
Error when trying to add into doubly linked list Java

Time:10-04

I have a Node class:

  public class Node<T> {
    private T data; // Entry in bag
    private Node<T> next; // Link to next node

    public Node(T dataPortion) {
        this(dataPortion, null);
    } 

    public Node(T dataPortion, Node<T> nextNode) {
        data = dataPortion;
        next = nextNode;
    } 

    public T getData() {
        return data;
    } 

    public void setData(T newData) {
        data = newData;
    } 

    public Node<T> getNextNode() {
        return next;
    } 

    public void setNextNode(Node<T> nextNode) {
        next = nextNode;
    } 
} 

And a DoublyLinkedNode as a subclass of Node

public class DoublyLinkedNode<T> extends Node<T> {

    private DoublyLinkedNode<T> previous; // Link to previous node

    public DoublyLinkedNode(T dataPortion) {
        super(dataPortion); // sets next to null as well
        previous = null;
    }

    public DoublyLinkedNode(T dataPortion, Node<T> nextNode) {
        super(dataPortion, nextNode);  // set next
        previous = null;
    }

    public DoublyLinkedNode(DoublyLinkedNode<T> previousNode, T dataPortion, DoublyLinkedNode<T> nextNode) {
        super(dataPortion, nextNode); // set next
        previous = previousNode;
    }

    public DoublyLinkedNode<T> getPreviousNode() {
        return previous;
    } 

    public void setPreviousNode(DoublyLinkedNode<T> previousNode) {
        previous = previousNode;
    } 
    
    public DoublyLinkedNode<T> getNextNode() {
        return (DoublyLinkedNode<T>) super.getNextNode();       
    }
}

Finally, the LinkedDeque class:

public class LinkedDeque<T> implements DequeInterface<T> {
    private DoublyLinkedNode<T> firstNode; // References node at front of deque
    private DoublyLinkedNode<T> lastNode; // References node at back of deque
    private int size;
    
    public LinkedDeque() {
        firstNode = null;
        lastNode = null;
        size = 0;
    }

    @Override
    public void addToFront(T newEntry) {
        size  ;
        DoublyLinkedNode<T> newNode = new DoublyLinkedNode<T>(null, newEntry, firstNode);
        if (isEmpty())
            lastNode = newNode;
        else 
            firstNode.setPreviousNode(newNode);
        firstNode = newNode;        
    }

    @Override
    public void addToBack(T newEntry) {
        size  ;
        DoublyLinkedNode<T> newNode = new DoublyLinkedNode<T>(lastNode, newEntry, null);
        if (isEmpty())
            firstNode = newNode;
        else 
            lastNode.setNextNode(newNode);
    }

    @Override
    public T removeFront() {
        T front = null;
    
    if (isEmpty()) {
        throw new EmptyQueueException();    
    } else {
        front = firstNode.getData();
        firstNode = firstNode.getNextNode();
        
        if (firstNode == null)
            lastNode = null;
        else 
            firstNode.setPreviousNode(null);
        size--;
    } 
    
    
    return front;
    }

    @Override
    public T removeBack() {
        T back = null;
        if (!isEmpty()) {
            back = lastNode.getData();
            lastNode = lastNode.getPreviousNode();
        
            if(lastNode == null)
                 firstNode = null;
            else 
                 lastNode.setNextNode(null);
            size--;
         } else {
             throw new EmptyQueueException();
         }
    
         return back;
    }

    @Override
    public T getFront() {
        T front = null;
        if (!isEmpty())
            front = firstNode.getData();
        
        return front;
    }

    @Override
    public T getBack() {
        T back = null;
        if (!isEmpty())
            back = lastNode.getData();
        
        return back;
    }

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

    @Override
    public void clear() {
        firstNode = null;
        lastNode = null;    
    }

    @Override
    public int size() {
        return size;
    }

    @Override
    public T[] toArray() {
        T[] result = (T[]) new Object[this.size];
        int index = 0;
        DoublyLinkedNode<T> pointer = firstNode.getNextNode();
        while (pointer != lastNode) {
            result[index] = (T) pointer;
            index  ;
            pointer = pointer.getNextNode();
        }
        return result;
    } 


} 

When I tried add an item to front using addToFront() method, there is an error saying that firstNode is null. I used debug to figure out the reason why but I still have no clue. I would like to learn how to fix this.

CodePudding user response:

@Override
    public void addToFront(T newEntry) {
        size  ;
        DoublyLinkedNode<T> newNode = new DoublyLinkedNode<T>(null, newEntry, firstNode);
        if (isEmpty())
            lastNode = newNode;
        else 
            firstNode.setPreviousNode(newNode);
        firstNode = newNode;        
    }

With first time using addToFront, firstNode is null. size == 1, so firstNode.setPreviousNode(newNode); will be called.

That's why you get NullPointerException

CodePudding user response:

A good practice would be to increase/decrease the size of list after the operation has been performed, if you increase/decrease the size before adding/removing and if it fails in between the size of the list will be in an inconsistent state.

That is one reason you application is performing inconsistently since size is already increased before the node is actually inserted (isEmpty() is not working as expected) thus giving you an NPE in some cases

In the method addToFront() the size is being increased before actually inserting node into the list thus isEmpty() method not working correctly, it should be something like this -

@Override
public void addToFront(T newEntry) {
    DoublyLinkedNode<T> newNode = new DoublyLinkedNode<T>(null, newEntry, firstNode);
    if (isEmpty())
        lastNode = newNode;
    else 
        firstNode.setPreviousNode(newNode);
    firstNode = newNode;
    size  ;
}

Also in the method addToBack() - if the list is empty firstNode and lastNode should point to the newly created node i.e firstNode = lastNode = newNode. -

    @Override
    public void addToBack(T newEntry) {
        
        DoublyLinkedNode<T> newNode = new DoublyLinkedNode<T>(lastNode, newEntry, null);
        if (isEmpty())
            firstNode = newNode;
        else 
            lastNode.setNextNode(newNode);
        lastNode = newNode;
        size  ;
    }

You may also wanna update the removeFront() and removeBack() methods to update the size correctly.

  • Related