Doubly Linked Lisl keeps getting null pointer error - java

I looked at all of the previous examples and cant see anything that I am doing wrong. I really struggle with null pointer exceptions for some reason and I just cant wrap my head around them.
public class DLBDictionary implements DictionaryInterface {
//Store Strings in an Node
public DLBNode firstNode;
public class DLBNode
{
public char value;
public DLBNode nextValue;
public DLBNode nextLetter;
public DLBNode(){
this.value = '/';
this.nextValue = null;
this.nextLetter = null;
}
public DLBNode(char value){
this.value = value;
this.nextValue = null;
this.nextLetter = null;
}
}
public DLBDictionary() {
DLBNode firstNode = new DLBNode('/');
}
// Add new String to end of list. If String should come before
// previous last string (i.e. it is out of order) sort the list.
// We are keeping the data sorted in this implementation of
// DictionaryInterface to make searches a bit faster.
public boolean add(String s) {
int charIndex = 0;
while(charIndex<=s.length())
{
char currentChar = s.charAt(charIndex);
boolean added = false;
while(!added)
{
if(firstNode.value == '/')
{
firstNode.value = currentChar;
added = true;
}
else if(firstNode.value == currentChar)
{
if(firstNode.nextLetter == null)
{
DLBNode newNode = new DLBNode();
firstNode.nextLetter = newNode;
firstNode = firstNode.nextLetter;
}
else
{
firstNode = firstNode.nextLetter;
}
added = true;
}
else
{
firstNode = firstNode.nextValue;
}
}
charIndex++;
}
DLBNode tempNode = new DLBNode('^');
firstNode.nextLetter = tempNode;
return true;
}
I left off the rest of my code but that last if statement is where I get the exception. It makes no sense to me! Didn't I initialize firstNode's value to '/' in the constructor? So firstNode.getValue should return '/' not a null pointer exception.

You should do
this.firstNode = new DLBNode();
in the constructor of DLBDictionary. You are actually creating a new object rather initializing your firstNode. Hope it helps.

You reset firstNode with several statements in the loop:
firstNode = firstNode.nextValue;
So it will happen that firstNode == null and this causes the NPE. The char value has nothing to do with it, it will be initialised to a character with value 0x00 anyway.

Related

How to create a linked list in java without importing linked lists

i am a CS student in college and i am having trouble with this project where i am supoosed to create a linked list using nodes without importing linked lists, as well as doing a some methods with the list. i am a beginner when it comes to coding, so assume i know nothing, because that is probably the case lol.
import java.io.*;
import java.lang.*;
public class List {
public int listCount = 0;
public char[] linkedList;
public List() throws FileNotFoundException {
}
public List(char[] array) throws FileNotFoundException {
if (array.length == 1) {
Node head = new Node(array[0]);
} else if (array.length > 1) {
Node head = new Node(array[0]);
Node traverse = head;
for (int i = 1; i < array.length; i++) {
while (traverse.nextNode != null) {
traverse = traverse.nextNode;
}
traverse.nextNode = new Node(array[i]);
listCount++;
}
}
}
public List(String w) throws FileNotFoundException {
char[] array2 = new char[w.length()];
for (int i = 0; i < w.length(); i++) {
array2[i] = w.charAt(i);
}
List str = new List(array2);
}
/* Find the character at a index
#param int index
return the character at the chosen index
*/
public char charAt(int index) throws IndexOutOfBoundsException {
char results = linkedList[0];
if (index < linkedList.length && index >= 0) {
results = linkedList[index];
}
return results;
}
public String concat(int index1, int index2) {
return null;
}
/* Determine if the list is empty
return whether the given conditions are true or false
*/
public boolean isEmpty() {
for (int i = 0; i < linkedList.length; i++) {
if (!linkedList.equals(null)) {
System.out.println("This list is not empty");
return false;
}
}
System.out.println("List is empty");
return true;
}
/* Determine the size of the list
return the size of the list
*/
public int size() {
return listCount;
}
/* Create a new String between 2 index's including the start and end index
#param beginIndex is the starting point of the new String
#endIndex is the ending point of new String
return the new String
*/
public String subString(int beginIndex, int endIndex) {
return null;
}
public void insert(Object x) throws IndexOutOfBoundsException {
if (listCount > 100 || listCount < 0) {
throw new IndexOutOfBoundsException("Bag is too large");
} else {
this.linkedList[listCount] = (char) x;
listCount++;
}
}
}
i appreciate any help or pointers ahead of time. we are using a separate node, helper, and driver class as well as a .txt file to assign into my list. i am stuck on the concat and substring methods too, but i want to make sure i am getting the framework correct first. thank you again.
If i understand your question correctly, you are asking how to access a specific type without importing it.
Imports are required to identify which type is referenced when it is used by its simple name. To reference a type without declaring it in the imports you need to use its fully qualified name. For instance
java.util.List<String> someList = new java.util.ArrayList<>();
works without importing List and ArrayList because by declaring the package the class is in it is clear which class is being referenced.
I'll try to do the code later, but here is a book that i found that may help you.
https://cin.ufpe.br/~grm/downloads/Data_Structures_and_Algorithms_in_Java.pdf
I bought a book about DATA STRUCTURE from Pearson company, and it's really a good book, but i don't remember much, it's something like this, that i did in a hurry:
public class List {
private Node head = null;
private Node foot = null;
private Node newNode = null;
private Node auxNode = null;
public List() {
this.head = new Node();
this.foot = new Node();
}
public class Node {
private int adress;
private Node nextNode;
}
public void add(int value) {
this.newNode = new Node();
newNode.adress = value;
if (head == null) {
// Head of the list receive the values of the NEW NODE, so the head of the list
// is not null enymore
head = newNode;
head.nextNode = null;
} else {
// In this case Head is not null
/*The auxiliary node will receive the head and the new Node will become the new Head from the list*/
auxNode = new Node();
auxNode = head;
/*
while(auxNode.nextNode != null ) {
}
auxNode = head;
//head of the list is empty, so we can add the new node
head = newNode;//Here the new node is empty because was transfered to the head
head.nextNode = auxNode; //The head of the list receive the old node that used to be the head
if (head.nextNode == null) {
head.nextNode = newNode;
} else if (head.nextNode != null) {
}*/
}
}
}
```
I hope this help you to get some lead

Infinite loop when replacing a node in an unsorted tree

I'm doing a homework assignment in Java where I have to create an unsorted binary tree with a String as the data value. I then have to write a function that replaces a Node and any duplicate Nodes that match an old description with a new object that contains a new description.
Here is the code that I am working with, including the test case that causes an infinite loop:
public class Node {
private String desc;
private Node leftNode = null;
private Node rightNode = null;
private int height;
public Node(String desc) {
this.desc = desc;
height = 0; // assumes that a leaf node has a height of 0
}
public String getDesc() {
return desc;
}
public Node getLeftNode() {
return leftNode;
}
public Node getRightNode() {
return rightNode;
}
public void setLeftNode(Node node) {
++height;
leftNode = node;
}
public void setRightNode(Node node) {
++height;
rightNode = node;
}
public int getHeight() {
return height;
}
public int addNode(Node node) {
if(leftNode == null) {
setLeftNode(node);
return 1;
}
if(rightNode == null) {
setRightNode(node);
return 1;
}
if(leftNode.getHeight() <= rightNode.getHeight()) {
leftNode.addNode(node);
++height;
} else {
rightNode.addNode(node);
++height;
}
return 0;
}
public static void displayTree(Node root) {
if(root != null) {
displayTree(root.getLeftNode());
System.out.println(root.getDesc());
displayTree(root.getRightNode());
}
}
public static Node findNode(Node current, String desc) {
Node result = null;
if(current == null) {
return null;
}
if(current.getDesc().equals(desc)) {
return current;
}
if(current.getLeftNode() != null) {
result = findNode(current.getLeftNode(), desc);
}
if(result == null) {
result = findNode(current.getRightNode(), desc);
}
return result;
}
public static void replaceNode(Node root, String oldDesc, String newDesc) {
if(oldDesc == null || newDesc == null) {
System.out.println("Invalid string entered");
return;
}
boolean replacedAllNodes = false;
while(replacedAllNodes == false) {
Node replace = findNode(root, oldDesc);
if(replace == null) { // No more nodes to replace
replacedAllNodes = true;
return;
}
replace = new Node(newDesc);
root.addNode(replace);
}
return;
}
public static void main(String[] args) {
Node root = new Node("test1");
Node test_2 = new Node("test2");
Node test_3 = new Node("test3");
Node test_4 = new Node("test4");
Node test_5 = new Node("test5");
Node test_6 = new Node("test6");
root.addNode(test_2);
root.addNode(test_3);
root.addNode(test_4);
root.addNode(test_5);
root.addNode(test_6);
displayTree(root);
replaceNode(root, "test4", "hey");
System.out.println("-------");
displayTree(root);
}
}
After testing the findNode method, and seeing that it returns the correct object, I realized that the infinite loop was being caused by my replaceNode method. I'm just not really sure how it is causing it.
I got it to work with one case by removing the while loop, but obviously that won't work for duplicates, so I'm wondering how I could remove the node with oldDesc and replace it with a new object that contains newDesc when there could be multiple objects with matching oldDesc data.
you are never changing root or oldDesc in your while loop
while(replacedAllNodes == false) {
Node replace = findNode(root, oldDesc);
if(replace == null) { // No more nodes to replace
replacedAllNodes = true;
return;
}
replace = new Node(newDesc);
root.addNode(replace);
}
If you watch
public static Node findNode(Node current, String desc) {
Node result = null;
if(current == null) {
return null;
}
if(current.getDesc().equals(desc)) {
return current;
}
if(current.getLeftNode() != null) {
result = findNode(current.getLeftNode(), desc);
}
if(result == null) {
result = findNode(current.getRightNode(), desc);
}
return result;
}
If the if(current.getDesc().equals(desc)) condition matches, replace will always be root so you are stuck in your while loop
Update:
If you dont necessarily have to replace the whole node, you could just update the description for your node at the end of your while loop.
instead of
replace = new Node(newDesc);
root.addNode(replace);
do something like:
root.setDesc(newDesc);
(of course you would have to create a setDesc() method first)
If you have to replace the whole object, you have to go like this:
Instead of
replace = new Node(newDesc);
root.addNode(replace);
do something like this:
replace = new Node(newDesc);
replace.setLeftNode(root.getLeftNode);
replace.setRightNode(root.getRightNode);
Plus you have to link the node that pointed to root so it points to replace like one of the following examples (depends on which side your root was of course):
nodeThatPointedToRoot.setLeftNode(replace);
nodeThatPointedToRoot.setRightNode(replace);
well looking at your code, you are not replacing a node you are just adding a new node to the edge of the tree and the old node would still be there so the loop will go forever and you can add a temp variable with an auto increment feature and to indicate the level of the node you are reaching to replace and you'll find it's just doing it again and again, instead of doing all this process how about just replacing the description inside that node ?

Null Pointers in my Queue (Link Lists)

Okay, I have this program almost done, but I'm lost at this point. I'm returning null pointers (it says on line 44 but that's just a while loop) and I need help fixing it please. I use a linked list to implement my queue, and my other two classes pass 100%, so the final class (CarQueue) is where the problem lies that is creating a Null Pointer.
public class CarQueue<E> {
private LinkNode<E> head;
private LinkNode<E> tail;
public CarQueue() {
head = null;
tail = null;
}
public CarQueue(E newData) {
LinkNode<E> temp = new LinkNode<E>(newData, null);
head = temp;
tail = temp;
}
public void addToQueue(E newData) {
LinkNode<E> temp = new LinkNode<E>(newData, null);
if (empty() == false) {
tail.setNext(temp);
tail = temp;
} else {
head = temp;
tail.setNext(temp);
tail = temp;
}
}
public String toString() {
LinkNode<E> temp = head;
String cars = "";
while (temp.getNext() != null) {
cars += temp.toString() + '\n';
}
return cars;
}
public E removeFmQueue() {
LinkNode<E> headReturn = head;
head = head.getNext();
return headReturn.getData();
}
public LinkNode<E> peek() {
return head.getNext();
}
public boolean empty() {
if (head == null)
return true;
else
return false;
}
}
If
while (temp.getNext() != null) {
is the line throwing an exception, then temp is null, (or, if it's even possible, getNext() is throwing a NullPointerException). But let's assume temp is the problem.
temp is being assigned to head, so is head being assigned to null?
If the zero-parameter constructor is called, but no other functions are called before calling toString(), then this would indeed result in temp being assigned null. Therefore, when you attempt temp.getNext(), a NullPointerException is thrown.
To prevent this, you could have an alternative value returned by the toString() method:
public String toString() {
if(head == null) {
return "no head. I got nothing.";
}
//print the other stuff...
}
But, really, the best solution is to never allow head--and therefore temp--to be null, as this means your class is in an unstable and basically-unusable state.
The most obvious way to prevent this is to eliminate the zero-parameter constructor--or alternatively have it only call the other constructor with a non-null value--and ensure that the other constructor never lets head remain as null.

Java Iterator Not Working With Single Iterable Object

I am having a problem with Iterators. I am writing a custom linked list as using an iterator to be able to traverse the list.
The iterator looks like this:
public class NodeIterator implements Iterator<Node> {
private Node current = head;
private Node lastReturned = head;
public boolean hasNext() {
return lastReturned.getLink() != null;
}
public Node next() {
lastReturned = current;
current = current.getLink();
return lastReturned;
}
public void remove() {
removeNode(lastReturned);
lastReturned = null;
}
}
I'm still in the early stages so I'm testing the data structures from the console by populating the nodes with this method.
private static void MethodToPopulateNodes() {
MyObject o = new MyObject();
String[] responses = new String[prompts.length];
scanner = new Scanner(System.in);
boolean done = false;
String s = null;
while (!done) {
int i = 0;
for (String prompt : prompts) {
System.out.println(prompt);
s = scanner.nextLine();
if (s.equalsIgnoreCase("stop")) {
done = true;
break;
} else {
responses[i] = s;
}
i++;
}
if (done) {
break;
}
o = new MyObject(responses);
myNode.add(c);
}
}
When I try to use the iterator when there is only one Node, it doesn't do anything. No errors or anything. However, if I have multiple nodes, this foreach works flawlessly.
public static void main(String[] args) {
myNode = new Node();
methodToPopulateLinkedList();
for (Node node : myNode) {
//toString is overridden for my object
System.out.println(node.getData().toString());
}
}
UPDATE: I edited the iterator to return hasNext() == true on the first iteration:
public class NodeIterator implements Iterator<Node> {
private boolean done = false;
private Node current = head;
private Node lastReturned = head;
public boolean hasNext() {
if (head == tail && head != null && !done) {
done = true;
return true;
}
return lastReturned.getLink() != null;
}
public Node next() {
lastReturned = current;
current = current.getLink();
return lastReturned;
}
public void remove() {
removeNode(lastReturned);
lastReturned = null;
}
}
I feel like that is super janky but it works. It seems like Java calls hasNext() first before calling next so I have to treat the special case differently.
|123
hasNext() == true
next() == 1
1|23
hasNext() == true
next() == 2
12|3
Where | equals the cursor. Is that accurate? Is there a better way to solve this?
If there's just one Node, it would have the special case of its ->next being null. Before the loop, try printing out the first node, I think your loop might be looking one ahead.

Null pointer exception in iterating and unable to search a node. The delete and replace methods are the ones that have problems

import javax.swing.*;
import java.io.*;
class MyDatabase implements Database {
Node head = null, tail = null, rover = null;
String ako;
File myFile = new File("sample.dat");
Node n = new Node();
Node current; Node p;
Node x = new Node();
public void insert(Node myNewNode) {
if (head == null){
head = myNewNode;
head.next = null;
}
else {
tail = head;
while(tail.next != null)
tail = tail.next;
tail.next = myNewNode;
myNewNode.next = null;
}
current = head;
}
public boolean delete(Node nodeToDelete) {
//the delete and replace methods are the ones that have problems
current = head;
p = head;
head = null;
//here, no matter what you enter, this if statement is never executed. Yes, never. even if they are equal.
if(nodeToDelete.title == head.title) {
head = head.next;
return true;
}
else{
while(current != nodeToDelete)
current = current.next;//Null Pointer exception here
while(p.next != nodeToDelete)
p = p.next;//Null Pointer exception here
current = current.next;
p = current;
}
current = head;//this is for listIterator purposes.
return true;
}
public boolean replace(Node nodeToReplace, Node myNewNode) {
//the delete and replace methods are the ones that have problems
//here i tested if the head.title and nodeToReplace.title have values
//the println correctly prints the value that I input
current = head;
String s = head.title;// for example i entered "max"
String s1 = nodeToReplace.title;// i also entered "max"
System.out.println(s);//prints out "max"
System.out.println(s1);// prints out "max"
if(s == s1) { // if statement is not executed. Note: i entered the same string.
myNewNode.next = head.next;
head = myNewNode;
}
else {
while(current != null) {
String s2 = current.title;
if(s2 == s1) {
current = new Node(myNewNode);
}
}
}
current = head;
return true;
}
public Node search(Node nodeToSearch) {
current = head;
while(current != null) {
if(current == nodeToSearch) {
Node p = new Node(current);
current = head;
return p;
}
}
return null;
}
public boolean saveToFile(String filename) throws Exception {
Node p = new Node();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(myFile));
out.writeObject(p);
out.close();
return true;
}
public boolean loadFromFile(String filename) throws Exception {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(myFile));
head = (Node) in.readObject();
return true;
}
public Node listIterator() {
try{
if(current == head) {
rover = current;
current = current.next;
return rover;
}
else {
rover = current;
current = current.next;
Node p = new Node(rover);
return p;
}
}
catch(NullPointerException e) {
current = head;
return null;
}
}
public Node listIterator2() {
try{
if(current == head) {
rover = current;
current = current.next;
return rover;
}
else {
rover = current;
current = current.next;
return rover;
}
}
catch(NullPointerException e) {
current = head;
return null;
}
}
public boolean equals(Database db) {
Node p;
while(rover != null) {
p = head;
while(p != null) {
if(rover != p)
return false;
p = p.next;
}
rover = rover.next;
}
return true;
}
public String whoIAm() {
ako = "Michael Glenn R. Roquim Jr. !";
return ako;
}
}
You trigger your own NPE:
// vv-- here you set head to null, just before you dereference it to access .title
head = null;
//here, no matter what you enter, this if statement is never executed. Yes, never. even if they are equal.
if(nodeToDelete.title == head.title) {
head = null;
//here, no matter what you enter, this if statement is never executed. Yes, never. even if they are equal.
if(nodeToDelete.title == head.title) {
you set head to null and immidiately after it you try to access it... (head is always null, so head.title will throw NPE)
also:
if(s == s1) { // if statement is not executed. Note: i entered the same string.
use equals() while comparing string, and not == (because otherwise you are looking for a same exact reference and not the same "string").
one more thing: it seems you will always throw NPE (when deleting) if your element is not in the list (you will not find the element, reach the end of the list which is null, and then try to address an instance variable in it).
I like cutting down code to the essentials so here is a working version which just does what the methods suggest.
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
class MyDatabase {
private final List<Book> titles = new ArrayList<Book>();
public void insert(Book title) {
titles.add(title);
}
public boolean delete(Book title) {
return titles.remove(title);
}
public boolean replace(Book title1, Book title2) {
int pos = titles.indexOf(title1);
if (pos >= 0) {
titles.set(pos, title2);
return true;
}
return false;
}
public Book search(String title) {
for (Book book : titles) {
if (book.title.equals(title))
return book;
}
return null;
}
public void saveToFile(String filename) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
out.writeObject(titles);
out.close();
}
public void loadFromFile(String filename) throws IOException, ClassNotFoundException {
ObjectInputStream in = new ObjectInputStream(new FileInputStream(filename));
titles.clear();
titles.addAll((List) in.readObject());
in.close();
}
public ListIterator<Book> listIterator() {
return titles.listIterator();
}
public boolean equals(Object o) {
return o instanceof MyDatabase && ((MyDatabase) o).titles.equals(titles);
}
public String whoIAm() {
return "Michael Glenn R. Roquim Jr. !";
}
}
class Book {
final String title;
final int year;
Book(String title, int year) {
this.title = title;
this.year = year;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
if (year != book.year) return false;
if (!title.equals(book.title)) return false;
return true;
}
}
Hmm, several problems here.
You set head to null, then promptly reference head.title. This will always throw a null pointer exception. I see someone else pointed that out.
You attemt to compare strings with ==. This won't work, it compares the address of the string, not the contents. Use equals.
When you check if the node matches the head node, you compare the titles. But when you compare to any other node, you do == on the node itself. You shouldn't have two different methods to compare nodes. As noted above, the title==title won't work. node==node might or might not work. How do you get a node to delete? If it is really the same node, i.e. the same object, as the node in the list that you are trying to delete, that's fine. But if it is a node constructed from, say, a user input, and so it will have maybe the same title as a node in the list, but not actually be the same object, this won't work. You probably want to say node.equals(node) and define an equals() function on node.
You set current to head and p to head, then you search starting from current, then you search starting from p. These should give identical results. Why do it twice?
If you don't find the node, you eventually hit a next value equal to null, but you just keep looking, thus generating a null-pointer exception.
As a point of style, it is better to define a variable within a function rather than as a member variable whenever possible.
Finally, may I suggest a little trick: Instead of having special handling for head all over the place, create a "sentinel", a fake node whose next pointer points to head. This really simplifies the code. For example:
class MyLinkedList
{
Node sentinel;
public MyLinkedList()
{
sentinel=new Node();
sentinel.next=null;
}
public void insert(Node myNewNode)
{
// This assumes new nodes must be added at the end. With a single-linked
// list, this requires traversing the entire list to reach the end.
Node current;
/* Note sentinel is never null, so we don't need any special handling here.
If the list is empty, sentinel.next is null, but that doesn't create
a special case.
*/
for (current=sentinel; current.next!=null; current=current.next) ;
current.next=myNewNode;
myNewNode.next=null;
}
public void insertAtStart(Node myNewNode)
{
// If we can add new nodes to the beginning, this is much faster.
myNewNode.next=sentinel.next;
sentinel.next=myNewNode;
}
public boolean delete(Node nodeToDelete)
{
Node current;
for (current=sentinel; current.next!=null; current=current.next)
{
if (current.next.equals(nodeToDelete)
{
current.next=current.next.next;
return true;
}
}
return false;
}
... etc ...

Categories