Node created inside of a for loop pointing to null?

Viewed 26

ContactList.java:

import java.util.Scanner;

public class ContactList {
   public static void main(String[] args) {
      Scanner scnr = new Scanner(System.in);
      
      ContactNode headNode = new ContactNode();
      ContactNode traverse = new ContactNode();
      String name;
      String phoneNum;
      String newLineEater;
      
      for (int i = 1; i < 4; i++){
     System.out.println("Person " + i);
     System.out.println("Enter name:");

      name = scnr.nextLine();
     System.out.println("Enter phone number:");
      phoneNum = scnr.nextLine();
      ContactNode newNode = new ContactNode(name, phoneNum);
      System.out.println("You entered: " + name + ", " + phoneNum);
      System.out.println();
      
      
      newNode.insertAfter(headNode);
      
      
      
      

      /* Type your code here. */
   
}

   System.out.println("CONTACT LIST");
 traverse = headNode.getNext();
 traverse.printContactNode();

   
   

}
}

And then:

public class ContactNode{
   
   private String contactName;
   private String contactPhoneNumber;
   private ContactNode nextNodePtr;
   
   public ContactNode(){
      
      contactName = "n/a";
      contactPhoneNumber = "no phone number";
      
   }
   public ContactNode(String contactName, String contactPhoneNumber){
      
      this.contactName = contactName;
      this.contactPhoneNumber = contactPhoneNumber;
      
   }
   
   public String getName(){
      
      return contactName;
      
      
   }
   
   public String getPhoneNumber(){
      
      return contactPhoneNumber;
      
   }
   
   public void printContactNode(){
      
   
         
      System.out.println("Name: " + this.contactName);
      
         
      }
      
    
      
      
      
   
   
   public ContactNode insertAfter(ContactNode prevNode){
      
      
     return this.nextNodePtr = prevNode;
      
      
      
   }
   
   public ContactNode getNext(){
      
      
      return this.nextNodePtr;
      
      
   }
   
}

The two class files are posted above. The error is: Exception in thread "main" java.lang.NullPointerException at ContactList.main(ContactList.java:37)

I thought that I could just reference the Node to test if it had pointed to something. It doesn't. Why? I understand that it NEEDS to point to something, but when I created the Nodes, I thought I had linked them together? What am I missing?

I'm trying to understand the fundamentals of linked lists, and any responses would be super helpful. Thank you!

1 Answers

Your code calls newNode.insertAfter(headNode); to insert a node. The definition is simple:

public ContactNode insertAfter(ContactNode prevNode) {
    return this.nextNodePtr = prevNode;
}

Let's walk through the execution.

Initial state:

.----------.
| headNode |
|   .next ====> null
`----------`

After adding a person (the new node is this in your insertAfter method; headNode is prevNode in the method):

.----------.   .----------.
| Person 1 |   | headNode |
|   .next ====>|   .next ====> null
`----------`   `----------`

We can actually stop here; if you add more people, they'll just point to headNode in tandem as Person 1 does, but headNode will always point to null.

Next you do:

traverse = headNode.getNext();
 traverse.printContactNode();

Here, traverse is null, so null.printContactNode(); crashes the program.


To build a linked list, the normal strategy is one of a few options:

  • Keep your insertAfter method as-is and build the list in reverse starting with the tail, but set the headNode = newNode at the end of your loop so you don't lose track of your nodes.

    The issue with this approach is that your first headNode is a dummy node, so you'll want to make sure to avoid it getting into your actual data node list by starting it out as null and then checking whether it's null or not before calling insertAfter. This should make it clear that insertAfter is really better named as insertBefore!

  • Traverse the whole chain of nodes at every addition in O(n). This lets you keep your head as-is, but you'll need to add a loop and change the logic in insertAfter -- maybe rename it insertAtEnd.

  • Keep a tail reference and use it to append to the list in O(1). Probably the best approach but requires adding another property to your ContactList class.

Related