This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I created a search method for a linked list. It works correctly when I search for something that does exist in the list. If I search for something not in the list, then I get a null pointer exception.
I don't see how its possible to get this exception.
Here is the method:
// these two search methods return the node containing the substring given
public UNode search(String cityName)
{
return search(cityName,this);//line 90
}//end search()-------------------------------------------------------------
private UNode search(String cityName, UNode current)
{
if(current != null)
{
if (current.getCity().getName().contains(cityName))
{
System.out.println("Node '" + current.getCity().getName()
+ "' has been found and returned.");
return current;
} else
{
return search(cityName,current.next);//line 105
}
}
else
{
System.out.println("No node containing the substring '"
+ cityName + "' can be found, returning null");
return null;
}
}//end search()-------------------------------------------------------------
To my understanding, this is what happens when searching for something that does not exist: The method keeps calling search() recursively with current.next, it gets to the last element and calls search(cityName, null), then since current is null, it says it is not found, and returns null.
Am I missing something here? What am I doing wrong? Should I just throw the null pointer exception?
Here is the method where I call the search method:
public static void uNodeTest(City[] cities)
{
UNode unvisited = new UNode();
unvisited.addCities(cities);
String a = unvisited.getNext().getNext().getNext().getCity().getName();
System.out.println(a);
UNode current = unvisited;
while(current.getNext() != null)
{
System.out.println(current.getCity().getName());
current = current.getNext();
}
UNode phil = unvisited.search("not a city");
}
Stack Trace:
java.lang.NullPointerException
at cityproject.UNode.search(UNode.java:105)
.
.
.
at cityproject.UNode.search(UNode.java:105)//(omitting repeats)
at cityproject.UNode.search(UNode.java:90)
at cityproject.CityProject.uNodeTest(CityProject.java:104)
at cityproject.CityProject.main(CityProject.java:79)
I would add a check before calling the recursive search to see if current.next is null:
if(current.next != null) {
return search(cityName,current.next);
}
else {
return null;
}
This might solve the null pointer exception...
Related
I'm trying to find a specific node in a binary tree using Java. My method for finding the node returns the node that contains the data that was searched for.
My code looks like this:
public BinNode find(Comparable item) throws NullPointerException {
if (item == null) {
throw new NullPointerException("item is NULL");
} else if (root == null) {
throw new NullPointerException("tree is empty");
}
return find(root, item);
}
public static boolean found = false;
public BinNode find(BinNode k, Comparable item) throws NullPointerException {
if (k.getData().equals(item)) {
found = true;
return k;
}
if (!found && k.getChildLeft() != null) {
find(k.getChildLeft(), item);
}
if (!found && k.getChildRight() != null) {
find(k.getChildRight(), item);
}
return k;
}
Running the debugger I can see, that when I search for an item that exists in the tree, it will find the correct node and go to the first return statement after "found" is set to true.
However, then compiler doesn't return that Node to the method call, but goes on to the second return statement, returning the root. So no matter where the Node is located, the method will always return the root.
What am I doing wrong?
Your method never returns "not found" which is fundamentally wrong because most of the times an item is not in the data. And that is your main problem. You need to return null / an empty Optional in the bottom return statement. And then you need to properly handle that "not found" return value when traversing the tree downwards, namely where you call find for the left and right child.
Your logic has to always be:
has the current node the correct value
if yes return the current node
does the left node contain the value
if yes return the corresponding node from the left
does the right node contain the value
if yes return the corresponding node from the right
return "not found" (because the current node is not correct and neither the left nor the right contain the value)
You currently skip / have not implemented the two nested "if yes return the corresponding node from the left/right" code paths.
(and of course remove the found variable as noted in a comment)
public BinNode find(BinNode k, Comparable item) throws NullPointerException {
if (k.getData().equals(item)) {
return k;
}
if (k.getChildLeft() != null) {
BinNode node = find(k.getChildLeft(), item);
if (node != null) return node;
}
if (k.getChildRight() != null) {
BinNode node = find(k.getChildRight(), item);
if (node != null) return node;
}
return null;
}
You need to return the finds from the left and right calls.
Your code finds the node and returns the k, but the other finds make no returns so your code continues on with code after the conditional statements, which is to return the node k. However, this falls back through the return stack to the original call to the double argument find, which has root as the BinNode given, so that is what is returned.
Refer Luk2302 answer.
You forgot "return" for left and right calls for find() function.
if (!found && k.getChildLeft() != null) {
return find(k.getChildLeft(), item);
}
if (!found && k.getChildRight() != null) {
return find(k.getChildRight(), item);
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Let's say I have 7 muppets on my list. They all have names (strings). The program returns the muppet (object) if their name is on the list. Now the problem is that how do I return null if none of the 7 muppets on my list match the parameter name? I know how to return null with the head node by simply returning null if the head node name is equal to null. But how do I do that with the rest of the list?
public Muppet peek(String name) {
if(start == null) { // if the start Muppet is equal to null, so there's nothing on the list
return null;
}
if(start.getName().equals(name)) { // return the muppet at the start of the list
return start;
} else {
Muppet previous = start;
while(!previous.getNext().getName().equalsIgnoreCase(name)) { // traverse through the whole list
previous = previous.getNext();
}
Muppet current = previous.getNext();
return current; // Return the muppet that was asked
}
}
This kind of linked list works well with recursion, and recursive solutions are sometimes simpler than iterative ones. Plus, since the recursion occurs at the end of the method the compiler may well optimize it to use a loop anyway.
public Muppet peek(String name) {
return find(start, name);
}
private Muppet find(Muppet head, String name) {
if (head == null) {
return null;
}
if (head.getName().equals(name)) {
return head;
}
return find(head.getNext(), name);
}
A simple iterative solution could look like this:
public Muppet peek(String name) {
Muppet current = start;
while (current != null) {
if (current.getName().equals(name)) { // or equalsIgnoreCase
break;
}
current = current.getNext();
}
return current;
}
I am using a linked list without using collections class for data structure practice.
I wanted to remove an element from the linked list after passing the element value to function
This is the function that i've written.
public boolean remove(String s)
{
if(head.getName().equalsIgnoreCase(s))
{
head = head.getNext();
return true;
}
else
{
Node p =head;
Node current=p.getNext();
while(true) {
if(current == null || current.getName().equals(s)) {
break;
}
p = current;
current = current.getNext();
}
if (current == null)
{
p.setNext(current.getNext());
return true;
}
}
return false;
}
i'm using Node p to store the previous node and current node.
The code falls in the return false section and there is no change in the list.Also i'm getting a null pointer exception warning in the p.setNext(current.getNext()) here.
Please let me know where i'm making mistake.
Regarding the Null Pointer Exception this should ring a bell
if (current == null)
{
p.setNext(current.getNext());
return true;
}
current is null and you are trying to invoke a method from it.
Also it doesn't seem you handle the corner cases like the list is empty or having one element.
current == null
is the not found case. When current == null we should return false, and calling current.getNext() will give the null pointer error. Similarly, the found case is not getting into the block you want. It should suffice, I think, to say if (current != null) where you have if (current == null)
I found https://www.geeksforgeeks.org/linked-list-set-3-deleting-node/ helpful.
Instead of checking true condition based on current value which possibly may or may not be null, you should be having one boolean flag.
This flag value can be made true if you find the passed element.
while(true) {
if(current == null || current.getName().equals(s)) {
flag = true;
break;
}
p = current;
current = current.getNext();
}
if (flag)
{
if(current!=null)
p.setNext(current.getNext());
return true;
}
I am implementing a stack using linked list in java. The problem is that I get a nullPointerException when there is no element below, e.g. the StackNode.link does not exist. Therefore if I try assigning the StackNode.link I get the Exception.
Using an if statement to only run the code if it exists, I just get the Exception in the if statement. How do I go about this?
int pop() {
StackNode temp = top;
// update top
top = belowTop;
belowTop = top.link; // this is where I get the nullPointExcpetion
return temp.data;
}
I would expect that when top.link does not exist (e.g. is null) then belowTop would just be null. This would be fine, but as described I get the exception.
EDIT: This is what I tried with the if-statement
if (top.link != null) {
belowTop = top.link;
}
else {
belowTop = null;
}
You need to check if the variable top has been initialized or not:
...
if (top != null) {
belowTop = top.link;
} else {
// Handle the not initialized top variable
}
...
Probably a good solution is to throw a runtime exception if belowTop if not initialized, like
...
if (top == null) {
throw new IllegalStateException("Can't pop from an empty stack");
}
belowTop = top.link;
...
In this case you have to prepare also a method that gives the ability to check if the stack is not empty or not initialized. Here a complete proposal:
public boolean isEmpty() {
// Your logic here
}
// Better have a public access because it seems an utility library and
// it should be accessed from anywhere
public int pop() {
StackNode temp = top;
// update top
top = belowTop;
if (top == null) {
throw new IllegalStateException("Can't pop from an empty stack");
}
belowTop = top.link; // Now it works
return temp.data;
}
And you can use it as follow:
if (!myStack.isEmpty()) {
int value = myStack.pop();
// Do something
}
Give this one a shot:
if (top.link != null) {
belowTop = top.link;
} else {
//handle the exception
}
The above checks if the top.link is null, which is a valid check and won't cause a nullPointerException.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am implementing a binary search tree in java, writing the methods recursively. I did the insert methods, and now I am stuck on the first traversal method, the in order one. When I call it in my test code, after adding a few elements, (tree.inorderTraversal), I get a null pointer exception at the rescursive in order method, and I don't see why. Could it be something wrong with the insert method?
public void insertInBinaryTree(E newItem)
{
BinaryTreeNode<E> node = new BinaryTreeNode<E>(newItem);
if (root == null) {
root = node;
} else {
insert(root, newItem);
}
}
// Recursively insert a node containing newItem into a non-empty tree. Used
// by insertInBinaryTree
private void insert(BinaryTreeNode<E> treeNode, E newItem)
{
if (newItem.compareTo(treeNode.getItem()) < 0) {
if (treeNode.getLeftChild() != null) {
insert(treeNode.getLeftChild(), newItem);
}
else {
treeNode.setLeftChild(new BinaryTreeNode<E>(newItem));
}
}
else {
if (treeNode.getRightChild() != null) {
insert(treeNode.getRightChild(), newItem);
}
else {
treeNode.setRightChild(new BinaryTreeNode<E>(newItem));
}
}
}
// If the tree is not empty, initiates an inorder traversal. This should
// print all items in ascending order. If the tree is empty, just prints
// "Tree is empty"
public void inorderTraversal()
{
System.out.println("\nInorder Traversal");
if (root == null) {
System.out.println("Tree is empty");
} else {
inorder(root);
}
}
// Recursive inorder traversal of a non-empty tree. Used by
// inorderTraversal.
private void inorder(BinaryTreeNode<E> treeNode)
{
inorder(treeNode.getLeftChild());
System.out.print(treeNode.getItem());
inorder(treeNode.getRightChild());
}
In the inorder method, since its recursive method the first statement should check for null on the argument and if it is so it should return. Otherwise the recursion never ends and it runs into NPE when accessing treeNode.getLeftChild() or treeNode.getRightChild() on possible null when there is no left child node or right child node.
You are missing NULL check. It should be
private void inorder(BinaryTreeNode<E> treeNode)
{
if(treeNode != null)
{
inorder(treeNode.getLeftChild());
System.out.print(treeNode.getItem());
inorder(treeNode.getRightChild());
}
}