NPE on LinkedList implementation, but I created the objects? - java

When main runs, the null pointer exception occurs at:
stringList.add("Test");
and specifically on this line of JAList in the add function:
dummy.getNextNode().setNodePrev(node);
I don't understand because at that point, dummy is initialized, dummy.getNextNode() is dummy, and node is initialized just before.
My only thought is that the constructor isn't setting the values properly when I call the constructor for JAList?
JAList<String> stringList = new JAList<String>();
As a side note, why don't you need the < E > when you create the constructor?
JANode.java:
public class JANode<E> {
private E value;
private JANode<E> next;
private JANode<E> prev;
public JANode(E value, JANode<E> next, JANode<E> prev)
{
this.value = value;
this.next = next;
this.prev = prev;
}
public E getValue()
{
return value;
}
public void setNodeNext(JANode<E> next)
{
this.next = next;
}
public JANode<E> getNextNode()
{
return next;
}
public JANode<E> getPrevNode()
{
return prev;
}
public void setNodePrev(JANode<E> prev)
{
this.prev = prev;
}
}
JAList.java:
public class JAList<E> {
private int initialCapacity;
private JANode<E> dummy;
public JAList()
{
this.initialCapacity= 10;
this.dummy = new JANode<E>(null, dummy, dummy);
}
public JAList(int initialCapacity)
{
this.initialCapacity = initialCapacity;
this.dummy = new JANode<E>(null, dummy, dummy);
}
public E add(E e)
{
JANode<E> node = new JANode<E>(e, dummy, dummy);
node.setNodeNext(dummy.getNextNode());
dummy.getNextNode().setNodePrev(node);
dummy.setNodeNext(node);
node.setNodePrev(dummy);
return e;
}
public JANode<E> getNode(E value)
{
JANode<E> local = dummy.getNextNode();
while (local != dummy && local.getValue() != value)
{
local = local.getNextNode();
}
return local;
}
}
main.java:
public class main {
public static void main(String[] args)
{
JAList<String> stringList = new JAList<String>();
stringList.add("Test");
stringList.add("B");
stringList.add("C");
System.out.println(stringList.getNode("Test").getValue());
System.out.println(stringList.getNode("Test").getNextNode().getValue());
}
}
Thank you.

Cause: At the moment of calling the constructor of JAList<E>, this line
this.dummy = new JANode<E>(null, dummy, dummy);
is the same that executing this:
this.dummy = new JANode<E>(null, null, null);
because you're using dummy as parameter but Java will initialize its value with null by default. Thus, when you later execute:
dummy.getNextNode().setNodePrev(node);
This part: dummy.getNextNode() returns null and it throws an NPE.
Solution: Change your code in the constructor to something like this:
this.dummy = null;
And in your add method, validate that is the current list is empty by evaluating if this.dummy is null:
public E add(E e) {
JANode<E> node = new JANode<E>(e, dummy, dummy);
if (dummy == null) {
dummy = node;
} else {
//your code for add goes here...
//note: it has errors as well...
//...
}
return e;
}

Related

How is this possible? (Junit exception testing of linked list implementation

I am writing a LinkedList implementation which includes a previous function that returns the position prior to the one passed as an input argument. It should check whether the inputted position is the first one and throw an exception in that case:
#Override
public Position<T> previous (Position<T> p) throws PositionException {
if (this.first(p)) {
throw new PositionException();
}
return this.convert(p).prev;
}
However, the following test is failing because it isn't throwing the expected exception from trying to use the previous function on the first position in the array:
#Test (expected=PositionException.class)
public void gettingPreviousAtFront() {
Position<String> one = list.insertFront("One");
Position<String> two = list.insertFront("Two");
assertTrue(list.first(two));
Position<String> beforeTwo = list.previous(two);
}
There was 1 failure: 1)
gettingPreviousAtFront(hw6.test.LinkedListTest)
java.lang.AssertionError: Expected exception:
exceptions.PositionException at
org.junit.internal.runners.statements.ExpectException.evaluate(ExpectException.java:32)
It is even passing the assertion on line 301 of the test that "two" is first. So how is it possible that the exception is not being thrown by the previous function?
Here is the full linkedlist code:
package hw6;
import exceptions.EmptyException;
import exceptions.PositionException;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedList<T> implements List<T> {
private static final class Node<T> implements Position<T> {
// The usual doubly-linked list stuff.
Node<T> next; // reference to the Node after this
Node<T> prev; // reference to the Node before this
T data;
// List that created this node, to validate positions.
List<T> owner;
#Override
public T get() {
return this.data;
}
#Override
public void put(T t) {
this.data = t;
}
}
/** This iterator can be used to create either a forward
iterator, or a backwards one.
*/
private final class ListIterator implements Iterator<T> {
Node<T> current;
boolean forward;
ListIterator(boolean f) {
this.forward = f;
if (this.forward) {
this.current = LinkedList.this.sentinelHead.next;
} else {
this.current = LinkedList.this.sentinelTail.prev;
}
}
#Override
public T next() throws NoSuchElementException {
if (!this.hasNext()) {
throw new NoSuchElementException();
}
T t = this.current.get();
if (this.forward) {
this.current = this.current.next;
} else {
this.current = this.current.prev;
}
return t;
}
#Override
public boolean hasNext() {
if (this.forward) {
return this.current != LinkedList.this.sentinelTail;
}
else {
return this.current != LinkedList.this.sentinelHead;
}
}
}
/* ** LinkedList instance variables are declared here! ** */
private Node<T> sentinelHead;
private Node<T> sentinelTail;
private int length; // how many nodes in the list
/**
* Create an empty list.
*/
public LinkedList() {
this.sentinelHead = new Node<>();
this.sentinelTail = new Node<>();
this.sentinelHead.owner = this;
this.sentinelTail.owner = this;
this.sentinelTail.prev = this.sentinelHead;
this.sentinelHead.next = this.sentinelTail;
this.length = 0;
}
// Convert a position back into a node. Guards against null positions,
// positions from other data structures, and positions that belong to
// other LinkedList objects. That about covers it?
private Node<T> convert(Position<T> p) throws PositionException {
try {
Node<T> n = (Node<T>) p;
if (n.owner != this) {
throw new PositionException();
}
return n;
} catch (NullPointerException | ClassCastException e) {
throw new PositionException();
}
}
#Override
public boolean empty() {
return this.length == 0;
}
#Override
public int length() {
return this.length;
}
#Override
public boolean first(Position<T> p) throws PositionException {
Node<T> n = this.convert(p);
return this.sentinelHead.next == n;
}
#Override
public boolean last(Position<T> p) throws PositionException {
Node<T> n = this.convert(p);
return this.sentinelTail.prev == n;
}
#Override
public Position<T> front() throws EmptyException {
if (this.length == 0) {
throw new EmptyException();
}
return this.sentinelHead.next;
}
#Override
public Position<T> back() throws EmptyException {
if (this.empty()) {
throw new EmptyException();
}
return this.sentinelTail.prev;
}
#Override
public Position<T> next(Position<T> p) throws PositionException {
if (this.last(p)) {
throw new PositionException();
}
return this.convert(p).next;
}
#Override
public Position<T> previous(Position<T> p) throws PositionException {
if (this.first(p)) {
throw new PositionException();
}
return this.convert(p).prev;
}
#Override
public Position<T> insertFront(T t) {
return this.insertAfter(this.sentinelHead, t);
}
#Override
public Position<T> insertBack(T t) {
return this.insertBefore(this.sentinelTail, t);
}
#Override
public void removeFront() throws EmptyException {
this.remove(this.front());
}
#Override
public void removeBack() throws EmptyException {
this.remove(this.back());
}
#Override
public void remove(Position<T> p) throws PositionException {
Node<T> n = this.convert(p);
n.owner = null;
n.prev.next = n.next;
n.next.prev = n.prev;
this.length--;
}
#Override
public Position<T> insertBefore(Position<T> p, T t)
throws PositionException {
Node<T> current = this.convert(p);
Node<T> n = new Node<T>();
n.owner = this;
n.data = t;
n.prev = current.prev;
current.prev.next = n;
n.next = current;
current.prev = n;
this.length++;
return n;
}
#Override
public Position<T> insertAfter(Position<T> p, T t)
throws PositionException {
Node<T> current = this.convert(p);
Node<T> n = new Node<T>();
n.owner = this;
n.data = t;
n.next = current.next;
current.next.prev = n;
n.prev = current;
current.next = n;
this.length++;
return n;
}
#Override
public Iterator<T> forward() {
return new ListIterator(true);
}
#Override
public Iterator<T> backward() {
return new ListIterator(false);
}
#Override
public Iterator<T> iterator() {
return this.forward();
}
#Override
public String toString() {
StringBuilder s = new StringBuilder();
s.append("[");
for (Node<T> n = this.sentinelHead.next; n != this.sentinelTail; n = n.next) {
s.append(n.data);
if (n.next != this.sentinelTail) {
s.append(", ");
}
}
s.append("]");
return s.toString();
}
}

java linked list compare with first element and remove using peek() method

created java linked list to add some data. want to compare first data inside that linked list. when i use peek() it not working. any other way to get front element and compare or how to write peek() method
LinkList class :
package list;
public class LinkList {
private class Node<T> {
public final T data;
public Node next;
public Node(T data) {
this.data = data;
}
public void displayNode() {
System.out.print(data + " ");
}
}
public static Node first = null;
private Node last = null;
public boolean isEmpty() {
return (first == null);
}
public <T> void addLast(T data) {
Node n = new Node(data);
if (isEmpty()) {
n.next = first;
first = n;
last = n;
} else {
last.next = n;
last = n;
last.next = null;
}
}
public void removeFirst() {
Node temp = first;
if (first.next == null) {
last = null;
}
first = first.next;
}
public void displayList() {
Node current = first;
while (current != null) {
current.displayNode();
current = current.next;
}
}
}
LinkListQueue:
package list;
public class LinkListQueue {
LinkList newLinkList = new LinkList();
public <T> void enqueue(T data) {
newLinkList.addLast(data);
}
public void dequeue() {
if (!newLinkList.isEmpty()) {
newLinkList.removeFirst();
}
}
public String displayQueue() {
newLinkList.displayList();
System.out.println();
return "";
}
public boolean isEmpty() {
return newLinkList.isEmpty();
}
}
LinkListQueueMain :
package list;
public class LinkListqueueMain {
public String getValue=null;
public static String displayQ = null;
static LinkListQueue queueImpl = new LinkListQueue();
static LinkList linkList = new LinkList();
public static void main(String[] args) {
runData();
}
public static void runData() {
queueImpl.enqueue("80%");
queueImpl.enqueue("70%");
queueImpl.enqueue("60%");
queueImpl.enqueue("85%");
queueImpl.enqueue("45%");
queueImpl.enqueue("55%");
for (int i = 0; i < 5; i++) {
System.out.println(linkList.toString());
}
}
}
This is my code. Any idea how to do that?
First you need to paramtrize the LinkList, not necessarily the node, as the LinkList is the public API to the outer world.
public class LinkList<T> {
private static class Node {
Then you could return the removed value. (removeFirst can throw a NullPointerException on an empty list.)
public T removeFirst() {
T removed = first.data;
if (first.next == null) {
last = null;
}
first = first.next;
return removed;
}
public T peekFirst() {
return first.data;
}

java.lang.NullPointerException in my custom class

I wish to implement a Queue based in a simple linked list class, without using java.util.
When I call the addEnd method in List class through enqueue method, I receive a java.lang.NullPointerException, though I expect the second element.
Which solution can I take?
The node class
public class Node {
private int value;
private Node next;
public Node(int val) {
value = val;
}
public Node(int val, Node next) {
value = val;
this.next=next;
}
public Node(Node next) {
this.next=next;
}
public int getValue() {
return value;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
public void displayNode() {
System.out.print(" "+value+" ");
}
}
My interface
public interface MyQueue {
void enqueue(int oVal);
int dequeue();
}
The List
public class List {
private Node first;
private Node last;
private int counter;
public List() {
first = null;
last = null;
}
public boolean isEmpty() {
return first==null;
}
public void addEnd(int val) {
Node n1 = new Node(val);
if( isEmpty() ) {
first = n1;
} else {
last.setNext(n1);
last = n1;
}
}
public int deleteStart() {
int temp = first.getValue();
if(first.getNext() == null){
last = null;
first = first.getNext();
}
return temp;
}
public void displayList() {
Node current = first;
while(current != null) {
current.displayNode();
current = current.getNext();
}
System.out.println("");
}
public int size() {
return counter;
}
}
The Queue
public class Queue implements MyQueue {
private List listQ;
public Queue() {
listQ = new List();
}
public boolean isEmpty() {
return listQ.isEmpty();
}
public void enqueue(int oVal) {
listQ.addEnd(oVal);
}
public int dequeue() {
return listQ.deleteStart();
}
public void displayQueue() {
System.out.print("Queue ");
listQ.displayQueue();
}
}
public class App {
public static void main(String[] args) {
Queue q1 = new Queue();
System.out.println("Two insertions");
q1.enqueue(4);
q1.enqueue(64);
q1.displayQueue();
System.out.println("Insert at the end : ");
q1.enqueue(23);
q1.displayQueue();
System.out.println("Delete an element at the begining of the queue");
q1.dequeue();
q1.displayQueue();
}
}
What #pens-fan-69 said is true. I'd like to add on to that. In order to make your code work, all you have to do is make sure last is set to first during the first insert:
public void addEnd(int val) {
Node n1 = new Node(val);
if( isEmpty() ) {
first=last=n1;
} else {
last.setNext(n1);
last = n1;
}
}
I tried running the code in online compiler and it works: http://goo.gl/99FyfY
You need to set the last reference when inserting to the empty list. The NullPointerException is because you use last before ever setting it.

LinkedList - delete(Object) method works strange - deleting last element doesn't work properly

I have LinkedList with test program. As you can see in that program I add some Students to the list. I can delete them. If I choose s1,s2,s3 oraz s4 to delete everything runs well, and my list is printed properly and information about number of elements is proper. But if I delete last element (in this situation - s5) info about number of elements is still correct, but this element is still printed. Why is that so? Where is my mistake?
public class Lista implements List {
private Element head = new Element(null); //wartownik
private int size;
public Lista(){
clear();
}
public void clear(){
head.setNext(null);
size=0;
}
public void add(Object value){
if (head.getNext()==null) head.setNext(new Element(value));
else {
Element last = head.getNext();
//wyszukiwanie ostatniego elementu
while(last.getNext() != null)
last=last.getNext();
// i ustawianie jego referencji next na nowowstawiany Element
last.setNext(new Element(value));}
++size;
}
public Object get(int index) throws IndexOutOfBoundsException{
if(index<0 || index>size) throw new IndexOutOfBoundsException();
Element particular = head.getNext();
for(int i=0; i <= index; i++)
particular = particular.getNext();
return particular.getValue();
}
public boolean delete(Object o){
if(head.getNext() == null) return false;
if(head.getNext().getValue().equals(o)){
head.setNext(head.getNext().getNext());
size--;
return true;
}
Element delete = head.getNext();
while(delete != null && delete.getNext() != null){
if(delete.getNext().getValue().equals(o)){
delete.setNext(delete.getNext().getNext());
size--;
return true;
}
delete = delete.getNext();
}
return false;
}
public int size(){
return size;
}
public boolean isEmpty(){
return size == 0;
}
public IteratorListowy iterator() {
return new IteratorListowy();
}
public void wyswietlListe() {
IteratorListowy iterator = iterator();
for (iterator.first(); !iterator.isDone(); iterator.next())
{
System.out.println(iterator.current());
}
System.out.println();
}
public void infoOStanie() {
if (isEmpty()) {
System.out.println("Lista pusta.");
}
else
{
System.out.println("Lista zawiera " + size() + " elementow.");
}
}
private static final class Element{
private Object value;
private Element next; //Referencja do kolejnego obiektu
public Element(Object value){
setValue(value);
}
public void setValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
//ustawia referencję this.next na obiekt next podany w atgumencie
public void setNext(Element next) {
if (next != null)
this.next = next;
}
public Element getNext(){
return next;
}
}
private class IteratorListowy implements Iterator{
private Element current;
public IteratorListowy() {
current = head;
}
public void next() {
current = current.next;
}
public boolean isDone() {
return current == null;
}
public Object current() {
return current.value;
}
public void first() {
current = head.getNext();
}
}
}
test
public class Program {
public static void main(String[] args) {
Lista lista = new Lista();
Iterator iterator = lista.iterator();
Student s1 = new Student("Kowalski", 3523);
Student s2 = new Student("Polański", 45612);
Student s3 = new Student("Karzeł", 8795);
Student s4 = new Student("Pałka", 3218);
Student s5 = new Student("Konowałek", 8432);
Student s6 = new Student("Kłopotek", 6743);
Student s7 = new Student("Ciołek", 14124);
lista.add(s1);
lista.add(s2);
lista.add(s3);
lista.add(s4);
lista.add(s5);
lista.wyswietlListe();
lista.delete(s5);
lista.wyswietlListe();
lista.infoOStanie();
lista.clear();
lista.infoOStanie();
}
}
The problem is that your setNext(Element next) method does not set anything if next == null. And that is the case for the last element of your list.
So when you call delete.setNext(delete.getNext().getNext());, nothing is actually set because delete.getNext().getNext() is null!
Remove the if (next != null) condition in setNext and it will work.

Implement Linked List in Java

I am trying to Implement a Linked List Using Java.
The code I have used is as follow
public class LinkNode
{
private int data;
public LinkNode next;
public LinkNode (int data)
{
this.data = data;
}
public void setData(int data)
{
this.data = data;
}
public int getData()
{
return this.data;
}
public void setNext(LinkNode next)
{
this.next = next;
}
public LinkNode getNext()
{
return this.next;
}
public static void main (String [] args)
{
LinkNode Node1 = new LinkNode(3);
LinkNode Head = Node1;
LinkNode Node2 = new LinkNode(4);
LinkNode Node3 = new LinkNode(5);
LinkNode Node4 = new LinkNode(6);
Head.setNext(Node1);
Node1.setNext(Node2);
Node2.setNext(Node3);
Node3.setNext(Node4);
int iCounter =0;
LinkNode currentNode= Head;
while (currentNode.getNext()!=null)
{
int data = currentNode.getData();
System.out.println(data);
currentNode = currentNode.getNext();
iCounter=iCounter+1;
}
System.out.println("No Of Nodes are"+iCounter);
}
}
The Problem here I am getting No of Nodes 3
The code is not counting the last Node that is Node4.
The out put is as follow
3
4
5
No Of Nodes are3
Please let me know what is the problem in the code.
To make Head point to Node1 write
Head = Node1;
If you write Head=null it means that Head doesn't point to any node, and you get a null pointer exception because you then try to get the next node from a node that doesn't exist.
The second problem is that you exit the loop when currentNode.getNext() returns null. The getNext() method returns null when you have reached the last node of the list; if you exit the loop then you won't count the last node. Change the loop condition into:
while (currentNode != null)
And please don't edit the question to ask followup questions. Nobody is notified when a question is edited, so you won't get new answers. It also makes the site less useful for future visitors. Post a new "question" for each question that you have.
Head, should not be null. Instead the data in head should be null, otherwise you have no way to find next.
Here is implementation of Singly Linked List I've developed years ago:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* #author sergiizagriichuk
*/
public class Node<T> {
private T value;
private Node<T> next;
public Node(T value) {
this.value = value;
}
public static <T> Node<T> createLinkedListFromArray(T... array) {
if (checkIfArrayIsNullOrEmpty(array)) return new Node<T>(null);
Node<T> head = new Node<T>(array[0]);
createLinkedList(array, head);
return head;
}
private static <T> boolean checkIfArrayIsNullOrEmpty(T[] array) {
return array == null || array.length == 0;
}
private static <T> void createLinkedList(T[] array, Node<T> head) {
Node<T> node = head;
for (int index = 1; index < array.length; index++) {
T t = array[index];
node.setNext(new Node<T>(t));
node = node.getNext();
}
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public Node<T> getNext() {
return next;
}
public void setNext(Node<T> next) {
this.next = next;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return value != null && value.equals(node.value);
}
#Override
public int hashCode() {
return value.hashCode();
}
#Override
public String toString() {
List ret = createList();
return Arrays.toString(ret.toArray());
}
private List createList() {
Node root = this;
List ret = new ArrayList();
while (root != null) {
ret.add(root.getValue());
root = root.getNext();
}
return ret;
}
}
And some Tests:
/**
* #author sergiizagriichuk
*/
public class NodeTest {
#Test
public void testCreateList() throws Exception {
Node<Integer> node = Node.createLinkedListFromArray(1, 2, 3, 4, 5);
Assert.assertEquals(Integer.valueOf(1), node.getValue());
Assert.assertEquals(Integer.valueOf(2), node.getNext().getValue());
}
#Test
public void testCreateListSize() throws Exception {
Integer[] values = new Integer[]{1, 2, 3, 4, 5};
int size = values.length - 1;
Node<Integer> node = Node.createLinkedListFromArray(values);
int count = 0;
while (node.getNext() != null) {
count++;
node = node.getNext();
}
Assert.assertEquals(size, count);
}
#Test
public void testNullNode() throws Exception {
Node<Integer> nullNode = new Node<Integer>(null);
assertNullNode(nullNode);
}
#Test
public void testNullArray() throws Exception {
Node<Integer> nullArrayNode = Node.createLinkedListFromArray();
assertNullNode(nullArrayNode);
}
#Test
public void testSetValue() throws Exception {
Node<Integer> node = new Node<Integer>(null);
assertNullNode(node);
node.setValue(1);
Assert.assertEquals(Integer.valueOf(1), node.getValue());
}
private void assertNullNode(Node<Integer> nullNode) {
Assert.assertNotNull(nullNode);
Assert.assertNull(nullNode.getValue());
}
}
Try to use or redevelop for your situation

Categories

Resources