Null pointer exception in Deque implementation - java

I am learning Java, and implementing a Deque data structure. This is the Node class:
import java.util.*;
public class Deque<Item> implements Iterable<Item> {
private Node sentinel;
private class Node {
Item item;
Node next;
Node previous;
Node(Item value) {
item = value;
next = this;
previous = this;
}
}
public Deque(Item item) // construct an empty deque
{
Node sentinel = new Node(item);
}
public boolean isEmpty() // is the deque empty?
{
return (size() == 0);
}
public int size() // return the number of items on the deque
{
System.out.println("size");
if (sentinel.next == sentinel) {
System.out.println("empty");}
return 0;
// }
// int count = 0;
// Node temp = sentinel;
// while (temp != sentinel)
// {
// count += 1;
// temp = temp.next;
// }
// return count;
}
public void addFirst(Item item) // insert the item at the front
{
if (item == null) {
throw new java.util.NoSuchElementException();
}
Node a = new Node(item);
if (isEmpty())
{
System.out.println("Hello world");
sentinel.next = a;
a.previous = sentinel;
}
else
{
sentinel.next.previous = a;
sentinel.next = a;
a.previous = sentinel;
}
}
public void addLast(Item item) // insert the item at the end
{
if (item == null)
throw new java.util.NoSuchElementException();
Node a = new Node(item);
sentinel.previous = a;
a.next = sentinel;
}
public Item removeFirst() // delete and return the item at the front
{
if (isEmpty())
throw new UnsupportedOperationException();
Item value = sentinel.next.item;
sentinel.next = sentinel.next.next;
sentinel.next.previous = sentinel;
return value;
}
public Item removeLast() // delete and return the item at the end
{
if (isEmpty())
throw new UnsupportedOperationException();
Item value = sentinel.previous.item;
sentinel.previous = sentinel.previous.previous;
sentinel.previous.next = sentinel;
return value;
}
public Iterator<Item> iterator() // return an iterator over items in order from front to end
{
return new DequeueIterator();
}
private class DequeueIterator implements Iterator<Item>
{
private Node current = sentinel;
public boolean hasNext() {
return current != null;
}
public void remove() {}
public Item next() {
Item value = current.item;
current = current.next;
return value;
}
}
public static void main(String[] args) // unit testing
{
System.out.println(Thread.currentThread().getStackTrace());
Deque<Integer> d = new Deque<Integer>(0);
System.out.println(d.isEmpty());
System.out.println(Thread.currentThread().getStackTrace());
// d.addFirst(10);
// System.out.println(d.size());
// System.out.println(d.removeLast());
}
}
Then when checking the size of the Deque as following:
public class Deque<Item> implements Iterable<Item> {
public Deque() // construct an empty deque
{
Node sentinel = new Node(null);
if (sentinel.next == sentinel)
System.out.println("empty");
}
}
The compiler error is NullPointerException. Is it due to the initialization of Node(null)? If yes, how can I input a zero value for the generic Item?
Stacktrace:
java.lang.NullPointerException
at Deque.size(Deque.java:29)
at Deque.isEmpty(Deque.java:24)
at Deque.main(Deque.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
And line 29 is:
if (sentinel.next == sentinel)

You're declaring a local variable called sentinel and assigning it instead of using the instance field and assigning it.
public Deque(Item item) // construct an empty deque
{
Node sentinel = new Node(item);
}
should be
public Deque(Item item) // construct an empty deque
{
this.sentinel = new Node(item);
}
otherwise the instance variable sentinel remains null and causes a NullPointerException when you try to dereference it
public int size() // return the number of items on the deque
{
System.out.println("size");
if (sentinel.next == sentinel) { // here
System.out.println("empty");
}
return 0;
}

If you get a NullPointerException on the following line:
if (sentinel.next == sentinel)
then the only cause can possibly be that sentinel is null. This is because in the constructor for Deque, you are creating a new variable called sentinel, not using the one in the class.

Related

Ovewriting toString method in deque class using generics

I am trying to print the first and last elements in a deque using a toString method however I'm not entirely sure if I am overwriting the toString method correctly.
As far as I can tell, the methods all seem to behave correctly but I have no way of being able to tell as I am unable to see any readable output.
I am aware that there is already a deque interface, however this is part of an exercise in using generics in Java.
This piece of code should create a deque, be able to add values to the front of the deque, remove values from the front, add values to the rear and remove values from the rear.
Here's the class in question:
import java.util.Iterator;
import java.util.NoSuchElementException;
class Deque<T> implements Iterable<T> {
private class Node<T> {
public Node<T> left, right;
private final T item;
public Node(T item) {
if (item == null) {
throw new NullPointerException();
}
this.item = item;
}
public void connectRight(Node<T> other) {
this.right = other;
other.left = this;
}
}
private class DequeIterator implements Iterator<T> {
private Node<T> curr = head;
public boolean hasNext() {
return curr != null;
}
public void remove() {
throw new UnsupportedOperationException();
}
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
T item = curr.item;
curr = curr.right;
return item;
}
}
private Node<T> head, tail;
private int size;
public Iterator<T> iterator() {
return new DequeIterator();
}
public Deque() {
}
public int size() {
return size;
}
public boolean isEmpty() {
return size() == 0;
}
public void checkInvariants() {
assert size >= 0;
assert size > 0 || (head == null && tail == null);
assert (head == null && tail == null) || (head != null && tail != null);
}
public void addFirst(T item) {
Node<T> prevHead = head;
Node<T> newHead = new Node<T>(item);
if (prevHead != null) {
newHead.connectRight(prevHead);
} else {
tail = newHead;
}
head = newHead;
size++;
checkInvariants();
}
public void addLast(T item) {
Node<T> newTail = new Node<T>(item);
Node<T> prevTail = tail;
if (prevTail != null) {
prevTail.connectRight(newTail);
} else {
head = newTail;
}
tail = newTail;
size++;
checkInvariants();
}
public T removeFirst() {
if (isEmpty()) {
throw new java.util.NoSuchElementException();
}
size--;
Node<T> prevHead = head;
head = prevHead.right;
prevHead.right = null;
if (head != null) {
head.left = null;
}
checkInvariants();
return prevHead.item;
}
public T removeLast() {
if (isEmpty()) {
throw new java.util.NoSuchElementException();
}
size--;
Node<T> prevTail = tail;
tail = prevTail.left;
prevTail.left = null;
if (tail != null) tail.right = null;
checkInvariants();
return prevTail.item;
}
#Override
public String toString() {
Node<T> currTail = tail;
Node<T> currHead = head;
head = currHead.right;
tail = currTail.left;
StringBuilder builder = new StringBuilder();
while (currHead != null && currTail != null) {
builder.append(currHead.item + "\n");
}
return builder.toString();
}
public static void main(String[] args) {
Deque<Double> d = new Deque<Double>();
d.addFirst(1.0);
System.out.println(d);
d.addLast(1.0);
//d.removeFirst();
//d.removeLast();
System.out.println(d.toString());
}
}
First of all, you're setting the instance variables head and tail to their respective neighbours, which is definitely not what you're out to do. This leaves your queue in an inconsistent state, where the second element is the head, but it still has a left neighbour, the original head. Same thing for the tail. Generally the toString method shouldn't have side effects.
Neither currTail nor currHead ever change in your while-loop, so your condition currHead != null && currTail != null will always be true if the deque is non-empty. You'd have to set those variables in the loop, however, you don't need to iterate from both ends at once. Iterating from the start will be enough. And then, you can use a for loop, like this:
#Override
public String toString() {
final StringJoiner stringJoiner = new StringJoiner("\n");
for (Node<T> node = head; node != null; node = node.right) {
stringJoiner.add(node.item.toString());
}
return stringJoiner.toString();
}
This sets the variable node to it's right neighbour after every iteration, and if the deque is empty, node will be null from the get-go and the loop will not be entered as is expected.
This is just the more concise (In my opinion) version of this:
#Override
public String toString() {
final StringJoiner stringJoiner = new StringJoiner("\n");
Node<?> node = head;
while (node != null) {
stringJoiner.add(node.item.toString());
node = node.right;
}
return stringJoiner.toString();
}
which is basically your attempt, just fixed.
Not that I've used a StringJoiner instead of a StringBuilder, as it allows you to set a delimeter that is used between each String, which is exactly what you're doing.

Having trouble with my CircularList

Right now I am trying to create a circular list, where when I use hasNext() from an Iterator it should always return true. However right now it is returning that it is not a circular list, and I am also having problems printing out the values (in this example Strings) of the ArrayList. Here is the CircularList class I created, which has a inner Node class for the objects that are put into the list:
public class CircularList<E> implements Iterable{
private Node<E> first = null;
private Node<E> last = null;
private Node<E> temp;
private int size = 0;
//inner node class
private static class Node<E>{ //In this case I am using String nodes
private E data; //matching the example in the book, this is the data of the node
private Node<E> next = null; //next value
//Node constructors, also since in this case this is a circular linked list there should be no null values for previous and next
private Node(E data){
this.data = data;
}
}
//end of inner node class
public void addValue(E item){
Node<E> n = new Node<E>(item);
if(emptyList() == true){ //if the list is empty
//only one value in the list
first = n;
last = n;
}
else{ //if the list has at least one value already
//store the old first value
temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if(size == 1){
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList(){
boolean result = false;
if(first == null && last == null){ //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
// TODO Auto-generated method stub
return new CircularIterator<E>(); //each time this method is called it will be creating a new instance of my Iterator
}
}
Here is the Iterator class I am making:
public class CircularIterator<E> implements Iterator<E> {
#Override
public boolean hasNext() {
return false;
}
#Override
public E next() {
// TODO Auto-generated method stub
return null;
}
#Override
public void remove() {
// TODO Auto-generated method stub
}
}
and finally the Test class:
public class Test {
static CircularList<String> c = new CircularList<String>(); //in this case it is a string list
static Iterator it = c.iterator();
public static void main(String[]args){
c.addValue("Bob");
c.addValue("Joe");
c.addValue("Jaina");
c.addValue("Hannah");
c.addValue("Kelly");
Iterate();
for(String val : c){
System.out.println(val);
}
}
private static boolean Iterate(){
boolean result = false;
if(!it.hasNext()){
System.out.println("Not a circular list!");
}
else{
result = true;
}
return result;
}
}
Again I am trying to get it to always return true, I think the problem lies with my hasNext() method, but I am not completely sure.
The main problem with your approach is you are using static inner classes - this is not necessary. Making the outer class generic is sufficient. The generic parameter is then inherited by the inner classes and all sorts of issues disappear.
Implementing an Iterator properly is subtle.
public static class CircularList<E> implements Iterable<E> {
private Node first = null;
private Node last = null;
private int size = 0;
private class Node {
private E data;
private Node next = null;
private Node(E data) {
this.data = data;
}
}
public void addValue(E item) {
Node n = new Node(item);
if (emptyList()) {
//only one value in the list
first = n;
last = n;
} else { //if the list has at least one value already
//store the old first value
Node temp = first;
//the new first is the input value
first = n;
//next value after first is the old first value
first.next = temp;
//if after this there will be only two values in the list once it is done
if (size == 1) {
last = temp;
}
//if the list is greater than one than the last value does not change, since any other values will be put before last in this case, and not replace it
//creating the circular part of the list
last.next = first;
}
size++;
}
public boolean emptyList() {
boolean result = false;
if (first == null && last == null) { //if there is no values at all
result = true;
}
return result;
}
#Override
public Iterator<E> iterator() {
return new CircularIterator(); //each time this method is called it will be creating a new instance of my Iterator
}
private class CircularIterator implements Iterator<E> {
// Start at first.
Node next = first;
public CircularIterator() {
}
#Override
public boolean hasNext() {
// Stop when back to first.
return next != null;
}
#Override
public E next() {
if (hasNext()) {
E n = next.data;
next = next.next;
if (next == first) {
// We're done.
next = null;
}
return n;
} else {
throw new NoSuchElementException("next called after end of iteration.");
}
}
}
}
public void test() {
CircularList<String> c = new CircularList<>();
c.addValue("A");
c.addValue("B");
c.addValue("C");
c.addValue("D");
for (String s : c) {
System.out.println(s);
}
}
Your main code was essentially correct - all I did was remove the unnecessary generics parameters from the inner classes.
Note that the way you add node to the list means that the items come out backwards. You could adjust that in your addValue method quite easily.
You can simply use following for circular iteration. This Circular list behave as same as other java.util.Lists. But it's iteration is modified. You don't need to care about it's performance tuning additionally. Because it's super class (LinkedList) is already well tested and enough stronger to use.
`public class CircularList extends LinkedList {
#Override
public Iterator<E> iterator() {
return createIterator();
}
//create new iterator for circular process
private Iterator<E> createIterator() {
return new Iterator<E>() {
private int index = 0;
#Override
public boolean hasNext() {
//no elements when list is empty
return isEmpty();
}
#Override
public E next() {
E node = get(index);
//rotate index
index++;
if (index == size()) {
index = 0;
}
return node;
}
};
}
}`

Implementing custom Iterator on a LinkedList

I am attempting to create a custom Iterator on a LinkedList class I have made. I have been asked to alter the add function so that it adds objects Term in order from smallest to largest. (Term is a simple class taking the form Term(int power))
I cannot figure out how to create a loop in addTerm() in order to keep searching the next element to see if it is larger than the current power in Term. Can anyone help?
import java.util.Iterator;
public class customImpl implements custom{
private static class Node {
Term data;
Node next;
}
private Node head;
private class TermIterator implements Iterator<Term> {
private Node current;
private TermIterator(Node start) {
current = start;
}
#Override
public boolean hasNext() {
return current != null;
}
#Override
public Term next() {
Term result = current.data;
current = current.next;
return result;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported");
}
}
/**
* Add a term to the expression
*
* #param term the term to be added.
*/
#Override
public void addTerm(Term term) {
TermIterator iterator = new TermIterator(head);
Node newNode = new Node();
while(iterator.hasNext()) {
if(term.getPower() > iterator.next().getPower()) {
newNode.next = head;
}
else newNode.data = term;
}
newNode.data = term;
newNode.next = head;
head = newNode;
}
/**
* Returns an iterator over elements of type {#code T}.
*
* #return an Iterator.
*/
#Override
public Iterator<Term> iterator() {
return new TermIterator(head);
}
}
You cannot easily use your iterator as it goes through values instead of nodes:
#Override
public void addTerm(Term term) {
Node newNode = new Node();
newNode.term = term;
Node smaller = null; //smaller holds last element smaller than new term
Node current = head;
while(current != null) {
if(term.getPower() > current.term.getPower()) {
smaller = current;
break;
}
current = current.next;
}
if (smaller == null) {
newNode.next = head;
head = newNode;
} else {
newNode.next = smaller.next;
smaller.next = newNode;
}
}
If you want to use iterator, than you should define the 'Node' iterator (and use it in your addTerm method), and re-use it to define the 'Term' iteraotr:
class NodeIterator implements Iterator<Node> {
Node next;
NodeIterator() {
next = head;
}
#Override
public boolean hasNext() {
return (next != null);
}
#Override
public Node next() {
if (next == null) throw new NoSuchElementException();
Node res = next;
next = next.next;
return res;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
class TermIterator implements Iterator<Term> {
final NodeIterator iter = new NodeIterator();
#Override
public boolean hasNext() {
return iter.hasNext();
}
#Override
public Term next() {
return iter.next().term;
}
#Override
public void remove() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

JAVA - Implementing Stack using linkedlists

I am trying to implement the stack i.e., DSAStack.java using my linked list i.e., DSALinkedList.java
How do I do it? I think I am supposed to have push() perform an insertFirst() and pop() do a peekFirst() and removeFirst() to get the LIFO behaviour? and what about isEmpty()
and the other methods?
I am not sure, please help me out. A clear explanation with a code would be much appreciable. Thank you in advance!
Here is the DSAStack.java
public class DSAStack implements Iterable {
public static int DEFAULT_CAPACITY = 100;
private DSALinkedList list;
private int count;
private Object[] stack;
public DSAStack() {
count = 0;
stack = new Object[DEFAULT_CAPACITY];
}
public DSAStack(int maxCapacity) {
count = 0;
stack = new Object[maxCapacity];
}
public int getCount() {
return count;
}
public boolean isEmpty() {
boolean empty = (count == 0);
return empty;
}
public boolean isFull() {
boolean full = (count == stack.length);
return full;
}
public void push(Object value) {
if (isFull())
throw new IllegalArgumentException("Stack is full");
else
stack[count] = value;
count++;
}
public Object pop() {
Object topVal = top();
count--;
return topVal;
}
public Object top() {
Object topVal;
if (isEmpty())
throw new IllegalArgumentException("Stack is empty");
else
topVal = stack[count-1];
return topVal;
}
public Iterator iterator() {
return list.iterator();
}
}
AND here is the DSALinkedList.java
import java.util.*;
public class DSALinkedList {
public DSAListNode head;
public DSAListNode tail;
Object[] newValue;
public DSALinkedList() {
head = null;
tail = null;
}
public void insertFirst(Object newValue){
DSAListNode newNd;
newNd = new DSAListNode(newValue);
if (head == null) {
head = newNd;
tail = newNd;
} else {
newNd.setNext(head);
head = newNd;
}
}
public void insertLast(Object newValue){
DSAListNode newNd;
newNd = new DSAListNode(newValue);
if(head == null){
head = newNd;
} else {
tail.next = newNd;
tail = newNd;
}
}
public boolean isEmpty() {
return (head == null);
}
public Object peekFirst(){
Object nodeValue;
if (head == null)
throw new IllegalArgumentException("head is empty");
else
nodeValue = head.getValue();
return nodeValue;
}
public Object peekLast(){
Object nodeValue;
if (head == null)
throw new IllegalArgumentException("head is empty");
else
nodeValue = tail.getValue();
return nodeValue;
}
public Object removeFirst(){
Object nodeValue;
if (head == null){
throw new IllegalArgumentException("head is empty");
} else {
nodeValue = head.getValue();
head = head.getNext();
}
return nodeValue;
}
}
Your DSAStack class is meant to be the interface between the user and linkedlist. So therefore the class provides the LIFO interface and forces it on the user. From here, it should hide the implementation from the linkedlist so the user doesn't have to worry about insertingLast or insertingFirst, they just want to insert.
So to answer your question. The DSAStack needs to perform the following actions:
- size() -> returns int size
- push(Object e) -> returns bool (able to be inserted)
- pop() -> returns Object and removes it from linkedlist
- peek() -> returns Object
- isEmpty() -> returns bool if empty
Your DSAStack isn't meant to hold any data. So you don't need the count or stack variable. Instead, we need to store these inside the DSALinkedList class. DSAStack should therefore instantiate a DSALinkedList object, pass the maxCapacity, and initiate the object.
When the user says that they want to use pop() on DSAStack, the class then needs to tell DSALinkedList, hey! I want to pop one of your objects! Now DSALinkedList needs to implement the details here.
Rewriting your code would be like this:
public DSAStack(int maxCapacity) {
list = new DSALinkedList[maxCapacity];
}
public int getCount() {
return list.size();
}
public boolean isEmpty() {
return list.isEmpty();
}
public boolean isFull() {
return list.isFull();
}
public void push(Object value) {
list.insertLast(value);
}
public Object pop() {
return list.removeLast();
}
public Object top() {
return list.peekLast();
}
public Iterator iterator() {
return list.iterator();
}
}

java.lang.NullPointerException in a little class

My java class comps up with a NullPointerException.Please help!
The error messages:
java.lang.NullPointerException at
RandomizedQueue.dequeue(52 line) at
RandomizedQueue$IndependantIterator.next (88 line) at
RandomizedQueue.main (104)
I have signed the line number in the end of the error code line.
import java.util.Iterator;
public class RandomizedQueue<Item> implements Iterable<Item> {
private int number=0;
private Node first=null;
private Node end=null;
private class Node {
Item item;
Node next=null;
Node last=null;
}
private Node Random() {
double r = Math.random();
int n = (int) (r*number);
if(n==0) n=1;
Node ob=first;
for(int i=0;i<(n-1);i++) {
ob = ob.next;
}
return ob;
}
public RandomizedQueue() {
Node empty=new Node();
}
public boolean isEmpty() {
return number==0;
}
public int size() {
return number;
}
public void enqueue(Item item) {
if(item==null) throw new NullPointerException();
number++;
if(first==null) {
first = new Node();
end = first;
first.item = item;
}
else {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
oldfirst.last = first;
}
}
public Item dequeue() {
Node ob=Random();
Item back=ob.item;
if(ob==end) {
end = ob.last;
ob.last.next=null; //52 line
}else if(ob==first) {
first=first.next;
first.last=null;
}
else {
ob.last.next=ob.next;
ob.next.last=ob.last;
}
return back;
}
public Node sample() {
return Random();
}
public Iterator<Item> iterator() {
return new IndepentRandomIterator();
}
private class IndepentRandomIterator implements Iterator<Item> {
private RandomizedQueue<Item> iq = new RandomizedQueue<Item>();
Node scan = first;
public IndepentRandomIterator() {
while(scan != null) {
iq.enqueue(scan.item);
scan=scan.next;
}
}
public boolean hasNext() {
return iq.number >0;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if(iq.number==0) throw new java.util.NoSuchElementException();
return iq.dequeue(); //88
}
}
public static void main(String[] args) {
RandomizedQueue<String> test = new RandomizedQueue<String>();
test.enqueue("Luo");
test.enqueue("Jiebin");
test.enqueue("is");
test.enqueue("genious");
test.dequeue();
test.dequeue();
StdOut.println("Is it empty?"+test.isEmpty());
StdOut.println("Size: "+test.size());
StdOut.println("A sample: "+test.sample());
Iterator<String> it = test.iterator();
while(it.hasNext()) {
String s = it.next(); //104
}
}
}
It's because ob.last is null. The only time that end is set is when item is first in enqueue(). And last is never set there. In dequeue(), it goes to the if block if ob == end. Since end.last == null, therefore ob.last == null too and ob.last.next will throw NPE.

Categories