addFirst(E e)双向链表(空指针异常)

时间:2014-10-28 10:32:44

标签: nullpointerexception add doubly-linked-list

import java.util.*;

public class MyTwoWayLinkedList<E> extends java.util.AbstractSequentialList<E> {
  private Node<E> head, tail;
  private int size = 0;
  private List<E> list;

  /** Create a default list */
  public MyTwoWayLinkedList() {
    list = new LinkedList<E>();
  }

  public MyTwoWayLinkedList(E[] objects) {
    list = new LinkedList<E>();

    for (int i = 0; i < objects.length; i++)
      add(objects[i]);
  }

  /** Return the head element in the list */
  public E getFirst() {
    if (size == 0) {
      return null;
    }
    else {
      return head.element;
    }
  }

  /** Return the last element in the list */
  public E getLast() {
    if (size == 0) {
      return null;
    }
    else {
      return tail.element;
    }
  }

  /** Add an element to the beginning of the list */
  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.previous = newNode; //link the old node with new 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;
  }

  /** Add an element to the end of the list */
  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
      newNode.previous = tail;
      tail = tail.next; // tail now points to the last node
    }

    size++; // Increase size
  }

  @Override /** Add a new element at the specified index 
   * in this list. The index of the head element is 0 */
  public void add(int index, E e) {
    if (index == 0) {
      addFirst(e);
    }
    else if (index >= size) {
      addLast(e);
    }
    else {
      Node<E> current = tail;
      for (int i = size - 1; i > index; i--) {
        current = current.previous;
      }
      Node<E> temp = current.next;
      current.next = new Node<E>(e);
      (current.next).previous = current;
      (current.next).next = temp;
      size++;
    }
  }

  /** Remove the head node and
   *  return the object that is contained in the removed node. */
  public E removeFirst() {
    if (size == 0) {
      return null;
    }
    else {
      Node<E> temp = head;
      head = head.next;
      head.previous = null;
      size--;
      if (head == null) {
        tail = null;
      }
      return temp.element;
    }
  }

  /** Remove the last node and
   * return the object that is contained in the removed node. */
  public E removeLast() {
    if (size == 0) {
      return null;
    }
    else if (size == 1) {
      Node<E> temp = head;
      head = tail = null;
      size = 0;
      return temp.element;
    }
    else {

      Node<E> temp = tail;
      tail = tail.previous;
      tail.next = null;
      size--;
      return temp.element;
    }
  }

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

      for (int i = size - 1; i > index; i--) {
        previous = previous.previous;
      }

      Node<E> current = previous.next;
      (current.next).previous = previous;
      previous.next = current.next;
      size--;
      return current.element;
    }
  }

  @Override /** Override toString() to return elements in the list */
  public String toString() {
    StringBuilder result = new StringBuilder("[");

    Node<E> current = tail;
    for (int i = size - 1; i > 0; 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();
  }

  @Override /** Clear the list */
  public void clear() {
    size = 0;
    head = tail = null;
  }

  @Override /** Override iterator() defined in Iterable */
  public ListIterator<E> listIterator() {    
    Node<E> current = head; // Current index 

    return list.listIterator();
  }

  @Override /** Override iterator() defined in Iterable */
  public ListIterator<E> listIterator(int index) {    
    Node<E> current = head; // Current index
    for (int i = 0; i < index; i++) { // sets current int to the parameter
        current = current.next;
      }

    return list.listIterator();
  }

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

  public class Node<E> {
    E element;
    Node<E> next;
    Node<E> previous;

    public Node(E element) {
      this.element = element;
    }
  }
}

这是我原来的课程,我将在下面包含我的测试用例,但首先让我解释一下我的问题。我正在尝试创建一个双向链表并向后迭代它。但是,我只是通过向列表中添加元素来获得Null指针异常。我现在已经查看了我的addFirst方法的代码部分大约2个小时,并且没有看到任何逻辑错误(并不意味着没有),请帮忙!

这是我承诺的测试用例。

  public class TestMyLinkedList {
  /** Main method */
  public static void main(String[] args) {
    // Create a list for strings
    MyTwoWayLinkedList<String> list = new MyTwoWayLinkedList<String>();

    // Add elements to the list
    list.add("America"); // Add it to the list
    System.out.println("(1) " + list);

    list.add(0, "Canada"); // Add it to the beginning of the list
    System.out.println("(2) " + list);

    list.add("Russia"); // Add it to the end of the list
    System.out.println("(3) " + list);

    list.addLast("France"); // Add it to the end of the list
    System.out.println("(4) " + list);

    list.add(2, "Germany"); // Add it to the list at index 2
    System.out.println("(5) " + list);

    list.add(5, "Norway"); // Add it to the list at index 5
    System.out.println("(6) " + list);

    list.add(0, "Poland"); // Same as list.addFirst("Poland")
    System.out.println("(7) " + list);

    // Remove elements from the list
    list.remove(0); // Same as list.remove("Australia") in this case
    System.out.println("(8) " + list);

    list.remove(2); // Remove the element at index 2
    System.out.println("(9) " + list);

    list.remove(list.size() - 1); // Remove the last element
    System.out.print("(10) " + list + "\n(11) ");

    for (String s: list)
      System.out.print(s.toUpperCase() + " ");

    list.clear();
    System.out.println("\nAfter clearing the list, the list size is " 
      + list.size());
  }
}

1 个答案:

答案 0 :(得分:0)

我不完全确定您在自己的双链接列表实现中使用LinkedList的原因。关于您关于addFirst方法的问题,我有以下评论以及如何处理此解决方案的示例。

调用addFirst方法时,head为null。 Head尚未初始化为新节点。 因此newNode.next = head;实际上是newNode.next = null;我想象你的空指针异常!

public void addFirst (E e)
{
    Node<E> newNode = new Node<E>(e); //create new node

    if (head != null){ //if head exists
        newNode.next = head; //the new node's next link becomes the old head
    }
        head = newNode; //the new head is the new node

    if (tail == null){ //if the tail is non existent ie head the only object in list
        tail = head; //the head and the tail are the same
        head.next = tail; //the 'next' value of head will be tail
    }
        head.prev = tail; //the previous node to head will always be tail
        size++;
    }   
}