When I add an element to my Deque and then immediately try to check it, it returns null. I've made sure the element going in is not null. What's the problem here:
Already tried checking that the methods are running, the add method runs in the DLL, and in the Deque. I've also tried queueTail and doing the queueing repeatedly and it still gives me the same NullPointerException
DoublyLinkedList class
public class DLL<T>{
private static class Node<T>{
T element;
Node<T> next;
Node<T> prev;
public T getElement() {
return element;
}
public void setElement(T element) {
this.element = element;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
public Node<T> getPrev() {
return prev;
}
public void setPrev(Node<T> prev) {
this.prev = prev;
}
public Node(T ele, Node<T> n, Node<T> p) {
element = ele;
next = n;
prev = p;
}
}
Node<T> header;
Node<T> trailer;
int size;
public DLL() {
size = 0;
header = new Node<>(null,null,null);
trailer = new Node<>(null,null,header);
header.setNext(trailer);
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public T first() {
if(isEmpty()) {
return null;
}
return header.getNext().getElement();
}
public T last() {
if(isEmpty()) {
return null;
}
return trailer.getPrev().getElement();
}
private void addBetween(T ele,Node<T> before, Node<T> after) {
Node<T> newN = new Node<T>(ele,after,before);
before.setNext(newN);
after.setPrev(newN);
size++;
}
public void addFirst(T ele) {
addBetween(ele,header.getNext(),header);
}
public void addLast(T ele) {
addBetween(ele,trailer,trailer.getPrev());
}
private T remove(Node<T> rem) {
Node<T> before = rem.getPrev();
Node<T> after = rem.getNext();
before.setNext(after);
after.setPrev(before);
size--;
return rem.getElement();
}
public T removeFirst() {
if(isEmpty()) {
return null;
}
return remove(header.getNext());
}
public T removeLast() {
if(isEmpty()) {
return null;
}
return remove(trailer.getPrev());
}
}
Deque class
public class Deque<T>{
private DLL<T> list = new DLL<>();
public Deque() {
}
public void queueHead(T ele) {
list.addFirst(ele);
}
public void queueTail(T ele) {
list.addLast(ele);
}
public T popHead() {
return list.removeFirst();
}
public T popTail() {
return list.removeLast();
}
public boolean isEmpty() {
return list.isEmpty();
}
public int size() {
return list.size();
}
public T peakHead() {
return list.first();
}
public T peakTail() {
return list.last();
}
}
My "Main" method, the part that runs and tries to use the Deque by adding a Graph ADT object into the Deque and then try to show it using a toString()
int population = Integer.parseInt((String) boxPopulation.getSelectedItem());
int perVacc = Integer.parseInt((String) boxVacc.getSelectedItem());
String disease = (String) boxDisease.getSelectedItem();
Disease d = null;
GraphMod grap = null;
com.graph.herdImmunity.Graph<Person> people;
if(disease.equalsIgnoreCase("Measles")) {
d = new Disease("Measles",12,95,6.5);
grap = new GraphMod(perVacc,d);
}
people = grap.initialise(population);//This just fills the graph with dummy data, this works I've tested
Deque<com.graph.herdImmunity.Graph<Person>> days = new Deque<>();
days.queueHead(people);
System.out.println(days.peakHead().toString());//this line gives me a nullpointerexception
Your addBetween
is wrong. It is overly complex and has confusingly named parameters. It should be something like:
private void addAfter(T ele, Node<T> after) {
Node<T> newN = new Node<T>(ele, after, after.getNext());
after.getNext().setPrev(newN);
after.setNext(newN);
size++;
}
Having both after
and before
will always introduce problems, you run the risk of confusing them (as you did) and you have no guarantee that they are consistent, what if I call the method with a mismatched pair of elements, that will corrupt the entire list.
You then need to call the method via:
public void addFirst(T ele) {
addAfter(ele, header);
}
public void addLast(T ele) {
addAfter(ele, trailer.getPrev());
}