So I'm coding in Java, and I had to make a LinkedList manually. It is doubly linked, and the tail's next pointer points to null. I'm using this to iterate through the list until I reach the end for a sorting algorithm (bubble sort).
Node<?> current = a.getHead();
while (current.getNext() != null) { //this line throw a NullPointerException
//sorting algorithm
current = current.getNext();
}
Here's the code for getNext() as well:
Node<?> current = a.getHead();.
Why is Java throwing a NullPointerException here?
Problem is in line Node<?> current = a.getHead();
a.getHead(); is returning null.
Please check like -
while (current != null && current.getNext() != null) {
//sorting algorithm
current = current.getNext();
}
Related
I was trying to read a program of removing duplicate elements in a linked list. I am confused about the break conditions put in the while loop. Below is the code.
public static <T> void removeDuplicates(SinglyLinkedList<T> list) {
SinglyLinkedList<T>.Node current = list.headNode; // will be used for outer loop
SinglyLinkedList<T>.Node compare = null; // will be used for inner loop
while ( current != null && current.nextNode != null) {
compare = current;
while (compare.nextNode != null) {
if (current.data.equals(compare.nextNode.data)) { //check if duplicate
compare.nextNode = compare.nextNode.nextNode;
} else {
compare = compare.nextNode;
}
}
current = current.nextNode;
}
}
The statement while ( current != null && current.nextNode != null) is confusing to me. If I remove current != null from the statement the output is produced same. Suppose the list is 1 -> 2 -> 3 -> null. Now initially current is at 1 , then if we traverse the list and when current points to 3 , at that moment (current.nextNode == null) and if I use only while( current.nextNode != null , that does the job for me. Then why the author has used current != null. Please help me clear the confusion.
A completely empty list would have current be null. The dot is the dereference operator - dereferencing null causes a NullPointerException. Hence, calling that method with an empty list would cause an NPE whereas the correct action is to do nothing ('remove all duplicates from this empty list' is a job that can be done, and it is done by doing nothing - there are no duplicates in an empty list, thus, nothing to remove).
For a non-empty list, indeed, that part of the while clause is never going to be relevant. Given that it would never get there (the last node in the list would already fail the while clause due to having a current.nextNode of null).
My problem is my delete method isn't deleting the node I want to delete and giving me a infinite loop.
public void delete(String name){
Node current = head;
boolean checker = false;
while(current != null && current.name != name && checker != true){
try{
if(current.name.equals(name)){
Node p = current.previous;
Node q = current.next;
/*The code can somehow get through only above this line, below here its not anymore*/
p.next = q;
q.previous = p;
System.out.println("Item successfully deleted.");
checker = true;
}else if(!current.name.equals(name) && current == tail){
System.out.println("Item not found.");
}
current = current.next;
} catch(NullPointerException e){}
}
}
Im here to asking for a hint or tip about my problem
(Sorry for my bad english)
You are checking if you have reached the end of the list current == tail but not breaking out of it. You can add a break statement inside your else if.
Other than that, you are using == to compare strings. I'm not sure why you added that there and it can be removed. Also, you must (almost always) never catch a NullPointerException.
"infinite loop" means your loop condition is incorrect, you are not making progress in each iteration, or there is a cycle your data. You use both current == null and current == tail to signify that it's the last element. Choice one way. Suggest you rewrite your loop condition to only deal with iteration, and have a conditional with a break if you have a match in the body:
for(current = head; current; current = current.next) {
if(current.name.equals(name)) {
if(current == head)
head = current.next
else
current.previous.next = current.next;
if(current == tail)
tail = current.previous;
else
current.next.previous = current.previous;
break;
}
// if tail.next is not initialized to null
// if(current == tail) break;
}
I see a potential infinite loop with no side effect here. If your list contain a node with node.name set to null then the invocation of current.name.equals(name) results in a NullPointerException. If you are at either end of the list the next or previous pointers will be null which will also result in the same exception. This exception is caught and discarded. Note that this prevents the advance of the current pointer which causes the same iteration to occur. At the very least make sure to print out the exception even if you're not taking any other action. It'll help with debugging.
Your while loop condition is overly complicated. while(current != null) should suffice given that:
Using if(current.name.equals(name)) removes the need for current.name != name. Also, don't use == or != for string comparison. It is a pointer comparison. Most equals methods take care of pointer comparisons.
Use a break or return for flow control here and remove checker boolean. The tail.next should always point to null to signify the end of the list. The only reason I see to have the checker boolean is if delete should remove all matching nodes and you want to know if it happened at least once. From what I see in the code that is not the case.
I would rewrite this as:
public void delete(String name){
Node current = head;
while(current != null){
try{
if(current.name.equals(name)){
...
return;
// Do not advance current here. Refer to finally block below.
}
} catch(NullPointerException e){
e.printStackTrace();
return; // If function should stop on error.
} finally {current = current.next;} // This prevents the repeat as it always happens.
}
System.out.println("Item not found.");
}
Note if you use "break" instead of "return" then the "Item not found." line will always print. You'd have to guard it with an if statement and a flag.
public void delete(String name){
Node current = head;
while(current != null){
if(current.name.equals(name)){
if(current.prev != null){
current.prev.next = current.next
}
if(current.next != null){
current.next.prev = current.prev
}
System.out.println("Removed node")
break;
}
current = current.next;
}
}
You could use this logic to delete the node that matches the name(given name is always present) if node is non null.
I can't see my error. I'm using a list where the insert method puts every new element added in order. I'm trying not to use hashtables for this case.
I wrote out a control flow graph, wrote it on paper, and it seems to make sense in those mediums but i'm not able to get the results i'm looking for.
My list: 0,1,1,1,2,4,5,7
It is the exact same after I run it through this method:
public class List {
int value;
List next;
List(int value, List next) {
this.value = value;
this.next = next;
}
}
public void deleteDuplicates() {
List marker = head;
List pointer = marker;
while(marker != null && marker.next != null){
while(pointer.next != null){
if(marker.value == pointer.next.value){
pointer.next = pointer.next.next;
}
else{
pointer = pointer.next;
}
}
marker = marker.next;
}
}
You are not resetting the pointer variable after the end of the inner loop: after marker = marker.next; you should add pointer = marker;
Also Node seems a better name rather than List.
The issue with your code is that you are having two pointers (marker and pointer) but not making any use of the second pointer (pointer). If you are coming across same value you are incrementing the pointer but eventually throwing away pointer without making any use of it.
A more succinct way to eliminate duplicates would be as follows -
List marker=head;
List pointer;
while(marker != null && marker.next != null){
pointer = marker.next;
while(pointer != null && marker.value == pointer.value){ //Skip nodes which have same value
pointer = pointer.next;
}
marker.next = pointer;
marker = marker.next;
}
In LinkedList we normally assign null value to last node and also use this condition to check for the last node.
I am checking for the last node with the same condition either its "next" node link is null or not. But I'm unable to handle NullPointerException when I get null value by the method "getNext".
while(lastNode.getNext() != null)
{
lastNode= lastNode.getNext();
}
I assume this is a custom implementation of a LinkedList; java.util.LinkedList does not have a getNext() method.
That said, what you want is:
while (current != null) {
past = current;
current = current.getNext();
}
return past;
I am assuming here that you want to return the last node, and that past is a variable of the same type as current.
I am using a binary tree structure here. I am getting a "NullPointerException" from the line containing the while statement. I am completely confused about why that would be.
BinaryTreeNode<CharData> currNode = theTree.findValue(data);
// Move up the Binary Tree to create code.
while(currNode.getParent() != null) {
// The loop does some stuff that doesn't
// affect what is assigned to currNode.
// Move to the parent node for the next iteration.
currNode = currNode.getParent();
} // End the while loop.
return code; // Return the string of binary code.
Find value is a method from my BinaryTree class that searches for and finds the node containing specific data. I know this works from testing it separately outside of this implementation.
The only reason why the while-loop statement can throw a NPE is, when currNode is null. I suspect findValue() returned null.
I guess one fix (when you care about the topmost node) would be:
while(currentNode != null) {
rootNode = currentNode;
currentNode = currentNode.getParent();
}
Or the typical pattern which relies on boolean shortcut evaluation:
while(curentNode != null && currentNode.getParent() != null)
Or my prefered solution using guards:
if (currentNode == null)
throw NotFound(); // or return something
while(curentNode.getParent() != null) {
If you see the code:
BinaryTreeNode<CharData> currNode = theTree.findValue(data);
I guess, currNode is getting some value if findValue() able to search data else it is returning NULL values.
When it returns a NULL value it will throw NPE.
To avoid it, you can modify your code a little bit.
while(currNode != null && currNode.getParent != null) {
// your code here
}