简体   繁体   中英

NullPointerException when iterating over linked list

The concept behind the code is to delete elements in a list that are greater than the element before it. In this case my nodes have an int data and are comparable through that. (The class these are in extends Comparable<>

The issue is when I get a nullpointexception when this code runs with the linked list:

 [2,5,4,3,7,6,4,2,3,4,5] 

The expected list that should be gotten is

[2,2]

Because (5 > 2) removes 5 then (4 > 2) removes 4 then (3 > 2) removes 3 ... and so on until it hits the end with a nullpointerexception.

Another example would be for the list

[3,1,-2,3,6,-1,3,2,1]

The list should end up being

[3,1,-2]

The debug code in there is to show which elements got removed.

The getter methods are basics and work fine.

public void deleteIncrementing() {
    T largest = null;

    while(head.getNext() != null || head != null) {
        Node<T> temp = head.getNext();

        while(temp.getValue().compareTo(head.getValue()) > 0){
            largest = temp.getValue();
            remove(largest);
            System.out.println(largest); // debug
            if(temp.getNext() == null){
                break;
            }
            temp = head.getNext();
        }
        head = temp;
    }
}

DERIVED FROM SUGGESTED PSEUDO-CODE:

    Node<T> current = head;
    Node<T> previous = null;

    while(current != null) {
        if (previous != null){
            if (current.getValue().compareTo(previous.getValue()) > 0){
                //System.out.println(current.getValue().toString());
                remove(current.getValue());
            }
            if (current.getValue().compareTo(previous.getValue()) < 0){
                //System.out.println(previous.getPrevious().getValue().toString());
                //System.out.println(current.getValue().toString());
                remove(previous.getValue());
            }
        }

        previous = current;
        current  = current.getNext(); 
    }

Which still isn't correct because it doesn't take in account the first to last element and keep the final one attached... any reasons?

For starters, this condition:

while (head.getNext() != null || head != null)

Should be:

while (head != null && head.getNext() != null)

Always check for nulls first !

I don't know whether this is the reason for you Exception but you you have to switch your tests in the while loop:

while (head != null && head.getNext() != null)

When you first test for head.getNext() != null and head is null a NullPointerException will be thrown

For more information look here

You are over-thinking this problem.

Consider what you need to accomplish: Write a function that delete LinkedList elements whose value is greater than that of the preceding element.

After reading this statement you should have an idea of what you need to consider at every point the LinkedList (eg the current element, and the previous element). So there is really no-need for a nested while loop.

Pseudo-code:

current  = head 
previous = null

while current is not null
   is previous non-null and current > previous?
      if yes: delete current
      if  no: do nothing

   previous = current
   current  = current.next 

See if you can use this pseudo-code to simplify your own code.

Besides the incorrect check on head that others have mentioned, I think there are some potential issues with this:

    while(temp.getValue().compareTo(head.getValue()) > 0){
        largest = temp.getValue();
        remove(largest);
        System.out.println(largest); // debug
        if(temp.getNext() == null){
            break;
        }
        temp = head.getNext();
    }
    head = temp;

temp will refer to a node that is about to get removed. What happens to that node? I don't know, because I don't know what list type this is or what remove does. However, unless the documentation of the list class made it clear that remove would not affect the node's "next" pointer, I wouldn't count on it. As a general rule, that kind of data should be saved before a remove call. (In other languages, where you might have a "remove" that also explicitly deallocates storage, it would definitely be necessary to save the link first.)

The more serious problem is, even if the "next" pointer stays the same, what happens at the end of the list. temp points to a node that is then removed. Its "next" pointer is null , so you break. But then you set head = temp , which means head now points to a node that is no longer in the list. I think you want head = temp only if you get to that point because of the compareTo --not if you get there because you hit the end of the list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM