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.
Related
I have written my own linked list and am reading integers from a file into the list and printing them out. However, only the head of my list is printing and nothing else. I've been staring at this code for so long I feel insane, can anyone help?
Method in a separate 'files' class that reads in a file of integers separated by whitespace. This method will take the next integer and add it to my linked list.
public void readValues() {
LinkedList list = new LinkedList();
while(scan.hasNextInt()) {
Integer someData = scan.nextInt();
list.addNode(someData);
}
list.printList();
}
This method is in my LinkedList class which takes the data sent from my readValues method in my files class.
public void addNode(Integer someData) {
myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (myNode.getNext() == null) {
myNode.setNext(myNode);
size ++;
}
else if (myNode.getNext() != null) {
while(myNode.getNext() != null) {
myNode = myNode.getNext();
}
myNode.setNext(myNode);
size++;
}
}
This method is also in my LinkedList class and successfully prints the head of my list which with my data is the number 40 followed by ---> and then nothing else. It should print ever other integer read in from my file.
public void printList() {
LinkedNode current = head;
if (head == null) {
System.out.print("list is empty");
return;
}
while(current != null) {
System.out.print(current.getElement());
System.out.print(" --> ");
current = current.getNext();
}
}
LinkedNode class:
public class LinkedNode {
Integer data;
LinkedNode next;
public LinkedNode(Integer someData, LinkedNode next) {
this.data = someData;
this.next = null;
}
public int getElement() {
return data;
}
public void setElement(Integer data) {
this.data = data;
}
public LinkedNode getNext() {
return next;
}
public void setNext(LinkedNode next) {
this.next = next;
}
public String toString() {
return data + "";
}
}
Your code has a small bug in the if else conditions in your addNode() method due to which your data is not getting added in the list.
Root Cause
When you add a new node to your list,
In the first iteration
The head is currently null and hence the first if conditions becomes true and your first node gets added (That's why you got the data 40).
In the Subsequent iteration(s)
your else if condition checks the myNode's next pointer which will always be null (as per the constructor) and thus it's next pointer points towards itself. The nodes created from here do not become the part of the list as the next pointer of head was never assigned to any of these and these nodes also point to themselves only.
Solution
I made a little modification in the if else conditions:
public void addNode(Integer someData) {
LinkedNode myNode = new LinkedNode(someData,null);
//initialize node if this is first element
if (head == null) {
head = myNode;
size++;
}
else if (head.getNext() == null) {
head.setNext(myNode);
size ++;
}
else if (head.getNext() != null) {
System.out.println("in second else if");
LinkedNode n = head;
while(n.getNext() != null) {
n = n.getNext();
}
n.setNext(myNode);
size++;
}
}
PS: Try debugging your code with dry run, it's a great mental exercise and helps in boosting the learning curve significantly too. All the best! :)
The problem is with your addNode() method. Inside the addNode() method you are first creating a new node named mynode. Now when the head is null it sets head to mynode, thats ok. But when the head is not null the mynode is not being added to the list. Thats why only the first element exist and other's are getting lost.
Hope this helps. Let me know if I can help with anything else. Happy coding!
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.
The line "if (l.head.item != 9" gave me the error it said something like object is not compatible with int. I am really confused on why is that? How to fix it?
/DListNode1/
/* DListNode1.java */
public class DListNode1 {
public Object item;
// public short[][] colorVal;
public DListNode1 prev;
public DListNode1 next;
DListNode1() {
item = 0;
prev = null;
next = null;
}
DListNode1(Object i) {
item = i;
prev = null;
next = null;
}
}
//////////////
/* Double linked list */
public class DList1 {
protected DListNode1 head;
protected DListNode1 tail;
protected long size;
public DList1() {
head = null;
tail = null;
size = 0;
}
public DList1(Object a) {
head = new DListNode1();
tail = head;
head.item = a;
size = 1;
}
public DList1(Object a, Object b) {
head = new DListNode1();
head.item = a;
tail = new DListNode1();
tail.item = b;
head.next = tail;
tail.prev = head;
size = 2;
}
public void insertFront(Object i) {
DListNode1 temp = new DListNode1(i);
if (size == 0) {
head = temp;
tail = temp;
}
else {
temp.next = head;
head.prev = temp;
head = temp;
} size++;
}
public void removeFront() {
if (size == 0) {
return;
}
else if (size == 1) {
head = null;
tail = null;
size--;
}
else {
head = head.next;
head.prev = null;
size--;
}
}
public String toString() {
String result = "[ ";
DListNode1 current = head;
while (current != null) {
result = result + current.item + " ";
current = current.next;
}
return result + "]";
}
/////////////
public static void main(String[] args) {
DList1 l = new DList1();
l.insertFront(9);
if (l.head.item != 9) {
System.out.println("head.item is wrong.");
As others have pointed out, the problem is that the type of l.head.item is Object, and you can't compare that with an int using != or ==.
Options:
Cast l.head.item to Integer or int:
// This could be done in one step if you wanted
int headValue = (int) l.head.item;
if (headValue != 9)
Or
// This could be done in one step if you wanted
Integer headValue = (Integer) l.head.item;
if (headValue != 9)
Or you could do it inline:
if ((int) l.head.item != 9)
Use equals instead, which will automatically box the int to an Integer.
if (!head.equals(9))
Make your type generic instead, so you'd have a DListNode1<Integer>, and you could then be certain that all node values were Integer references (or null), and the != check would automatically unbox the Integer to an int and work.
Personally I'd definitely make this generic, but my guess is that you're relatively new to Java, and might not want to start with generics just yet.
Note that there's a difference between using equals and performing the unboxing: if the value of l.head.item is a reference to a non-Integer object, the first approach will throw a ClassCastException and the second will just go into the body of the if statement (as a string is not equal to 9, for example). Which of those is preferable depends on what you're trying to achieve in your bigger program: if it's entirely reasonable for your list to contain non-integers, you should use the equals check; if it actually indicates a programming error, then an exception is preferable as it alerts you to the error more quickly and stops your program from proceeding with invalid assumptions.
In both cases if l.head.item is null, you'll get a NullPointerException. This could be "fixed" using:
if (!Integer.valueOf(9).equals(l.head.item))
... but again it depends on what you want your code to do if the value is null.
Because a DListNode1.item is an Object not an Integer. Try casting to a Integer and compare to an Integer (9)
Compare using equals method.'==' will compare the refrence.
if(l.head.item.equals(new Integer(9))==false)
It will give you error because int is primitive:
Incompatible operand types Object and int
Change your code to:
if (!l.head.item.equals(new Integer(9))) {
Hope this helps.
I am having a really frustrating issue:
I am trying to run an iterator, but it keeps on coming up with java.lang.NullPointerException at the hasNext class.
I am not quite sure where it might be trying to use a null value. I am assuming it is something to do with current. I added a if statement to check if current is null. But then it returns and unexpected value.
Help appreciated.
Code below:
private class Iterator implements Iterator
{
private Link<T> current;
public boolean hasNext () {
if(current.next == null)
return false;
return true;
}
public T next() throws OutOfBounds
{
if (this.hasNext())
{
T element = current.element;
current = current.next;
return element;
}
else
throw new OutOfBounds("No next element to call");
}
}
private class Link<T>
{
private T element;
private int priority;
private Link<T> next;
public Link(T t, int p, Link<T> n)
{
this.element = t;
this.priority = p;
this.next = n;
}
}
}
You are probably not initializing current, so your check in the method hasNext should compare for null against currnet before checking against current.next
Modify your check
if(current.next == null)
to:
if(current == null || current.next == null)
Or modify your method as:
public boolean hasNext () {
return (current != null && current.next != null);
}
Try to update your hasNext as below to find the issue:
public boolean hasNext () {
if(current == null) {
System.out.println("current is null");
return false;
} else if(current.next == null)
return false;
}
return true;
}
You may use iterator.next() two times inside your while block.
Make new object with iterator.next() then use it.
This is the correct way to use it
ArrayList<String> demo = new ArrayList<>();
demo.add("A");
demo.add("B");
demo.add("C");
demo.add("D");
System.out.println(demo);
//Get iterator
Iterator<String> iterator = demo.iterator();
//Iterate over all elements
while(iterator.hasNext()){
/* if you want to use the elemet two times then put in a varialbe and use it.*/
//Get current element
String value = iterator.next();
System.out.println("fist time using"+ value)
System.out.println( "second time using " + value );
}
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 ...