Iterator - Null Pointer Exception Error - java

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 );
}

Related

Why am I getting a null pointer exception in my iterator? [duplicate]

This question already has answers here:
Why comparing Integer with int can throw NullPointerException in Java?
(7 answers)
Closed 7 years ago.
When calling my iterator over a doubly linked list, I am getting a null pointer exception. The null pointer exception occurs in main at line assertEquals(i, (int) it.next());
/***************************
* nested class DequeIterator
***************************/
private class DequeIterator implements Iterator<E>
{
// instance data member of ListIterator
private Node current;
// constructors for ListIterator
public DequeIterator()
{
current = first; // head in the enclosing list
}
public boolean hasNext()
{
return current != null;
}
public E next()
{
if (hasNext() == false){ throw new NoSuchElementException();}
else {
E ret = current.item;
current = current.next;
return ret;
}
}
public void addLast(E item) {
if (item.equals(null)) { throw new NullPointerException(); }
else {
Node node = new Node(item, null);
Node ptr = last;
ptr.prev.next = node;
node.next = ptr;
node.prev = ptr.prev;
ptr.prev = node;
N++;
}
}
public static void main(String[] args) {
Deque<Integer> lst = new Deque<Integer>(); // empty list
for(int i = 1; i <= 5; i++) {
lst.addLast(i);
}
assertEquals(5, lst.size());
Iterator<Integer> it = lst.iterator();
int i = 1;
while(it.hasNext()) {
assertEquals(i, (int) it.next());
i++;
}
assertEquals(6, i);
assertEquals(5, lst.size());
}
Can anybody tell me why I am getting a null pointer exception at that point?
Because the Integer wrapper type is nullable and in your queue you have a null Integer that you then try to cast as int primitive type ...
Try to put a conditional check verifying that the element is not null like this :
while(it.hasNext()) {
Integer e = it.next();
if(e != null)
assertEquals(i, (int)e );
i++;
}
Start off by looking at the termination condition for the loop:
public boolean hasNext(){
return current != null;
}
This means that the last time it runs, it will return null, since it only checks that the current element, not the next element, is non-null.
So your code becomes something like this:
Integer it_next = null;
assertEquals(i, (int)it_next);
And that cast to int is what's throwing the exception. If you look at the rules for how unboxing works, you can figure out why:
If r is a reference of type Integer, then unboxing conversion converts r into r.intValue()
So your code becomes similar to
((Integer)null).intValue();
which is a method call on a null value, causing the exception.
Presumably, the fix you want for this is to not return true in hasNext if the next value is null. Something like this:
public boolean hasNext(){
return current != null && current.next != null;
}
Given the incomplete code that you posted, it appears that there is a marker for the end of the deque called last, and that its item is most likely null.
Correct your iterator to check for last in hasNext():
public boolean hasNext()
{
return current != last && current != null;
}
The check for null has been retained for safety. It is probably not necessary.

Whats wrong with my delete method in LinkedList (generic)?

I changed the LinkedList class, but it still does not work
LinearNode class
public class LinearNode<T>{
private LinearNode<T> next;
private T element;
public LinearNode()
{
next = null;
element = null;
}
public LinearNode (T elem)
{
next = null;
element = elem;
}
public LinearNode<T> getNext()
{
return next;
}
public void setNext (LinearNode<T> node)
{
next = node;
}
public T getElement()
{
return element;
}
public void setElement (T elem)
{
element = elem;
}
}
I can't figure out the problem with delete method in my java generic class
public void delete(T element){
LinearNode<T> previous = list;
LinearNode<T> current = list;
boolean found = false;
while (!found && current != null)
{
if (current.getElement ().equals (element)) {
found = true;
}
else {
previous = current;
current = current.getNext();
}
}
//found loop
if (found)//we fount the element
{
if(current == this.list){
previous.setNext (null);
this.last = previous;
}
else
if(current == this.last){
this.last.setNext(null);
this.last.equals(previous.getElement());
}
else{
previous.setNext(current.getNext());
current.setNext (null);
}
this.count--;
}
}
I have also my driver class which will delete the element from the linked list
also here the part of driver class
public void delete(){
Teacher aTeacher;
Scanner scan = new Scanner(System.in);
String number;
aTeacher = new Teacher();
System.out.println("Now you can delete teachers from the programme by their number.");
System.out.println("Please input number:");
number = scan.nextLine();
if (aTeacher.getNumber().equals(number)){
teachers.delete(aTeacher);
}
else {
System.out.println("There are no any teacher with this number.");
}
}
I can see a few problems in your code.
This loop is a little odd
while (current != null && !current.getElement().equals(element))
{
previous = current;
current = current.getNext();
found = true;
}
You shouldn't be setting found = true inside the loop on every iteration, because then you will always believe that you found the element after the loop is done. If you pass in values that you know exist in the list, then you wouldn't notice a problem. If you pass in values that are not in the list, then you will likely see current set to null later in your code.
I might write this instead
while (! found && current != null)
{
if (current.getElement ().equals (element)) {
found = true;
}
else {
previous = current;
current = current.getNext();
}
}
This block is a little odd too
if(current == this.last){
this.last.setNext(null);
this.last.equals(previous.getElement());
}
Neither of these statements seem like they would have any effect. The value of last.getNext () should already be null. this.last.equals(previous.getElement()) is merely testing whether the last node is equal to the element held in the next to last node; that evaluation should always be false and hopefully has no side-effects.
I might write this instead
if(current == this.last){
previous.setNext (null);
this.last = previous;
}
Finally, though it's not a problem for the delete per se, I would still be thorough here and make sure that the node being removed doesn't retain any references into the list.
So this
previous.setNext(current.getNext());
might become this
previous.setNext(current.getNext());
current.setNext (null);

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.

LinkedList - loop not working - Java

I am required to write a method that returns a number - the amount of times an element is found in a linked list. So far I have;
package Question4;
import net.datastructures.Node;
public class SLinkedListExtended<E> extends SLinkedList<E> {
// returns the number of occurrences of the given element in the list
public int count(E elem) {
Node<E> cursor = tail;
int counter = 0;
if ((cursor != null) && (!(cursor.getElement().equals(elem)))) { //tail isnt null and element is not equal to elem
cursor = cursor.getNext(); //go to next node
} else if ((cursor != null) && (cursor.getElement().equals(elem))){ //cursor isn't null and element equals elem
counter++; //increment counter
}
else {
return counter; //return counter
}
return counter;
}
public static void main(String[] args) {
SLinkedListExtended<String> x = new SLinkedListExtended<String>();
x.insertAtTail("abc");
x.insertAtTail("def");
x.insertAtTail("def");
x.insertAtTail("xyz");
System.out.println(x.count("def")); // should print "2"
x.insertAtTail(null);
x.insertAtTail("def");
x.insertAtTail(null);
System.out.println(x.count("def")); // should print "3"
System.out.println(x.count(null)); // should print "2"
}
}
I have extended to a class which compiles correctly, so I know the problem is in my method. I can't figure out what to do, my code returns 0, which is probably the counter integer remaining at 0 and not going through the loop statement. Any ideas are appreciated.
Edit. SLinkedList code:
import net.datastructures.Node;
public class SLinkedList<E> {
protected Node<E> head; // head node of the list
protected Node<E> tail; // tail node of the list (if needed)
protected long size; // number of nodes in the list (if needed)
// default constructor that creates an empty list
public SLinkedList() {
head = null;
tail = null;
size = 0;
}
// update and search methods
public void insertAtHead(E element) {
head = new Node<E>(element, head);
size++;
if (size == 1) {
tail = head;
}
}
public void insertAtTail(E element) {
Node<E> newNode = new Node<E>(element, null);
if (head != null) {
tail.setNext(newNode);
} else {
head = newNode;
}
tail = newNode;
size++;
}
public static void main(String[] args) { // test
SLinkedList<String> list = new SLinkedList<String>();
list.insertAtHead("lol");
}
}
Maybe you should use a while loop instead of an if clause
**while** ((cursor != null) && (!(cursor.getElement().equals(elem)))) {
The code in count is not in a loop, so it'll just return after the first element.
Try this:
public int count(E elem) {
Node<E> cursor = tail;
int counter = 0;
while (true)
{
if ((cursor != null) && (!(cursor.getElement().equals(elem)))) { //tail isnt null and element is not equal to elem
cursor = cursor.getNext(); //go to next node
} else if ((cursor != null) && (cursor.getElement().equals(elem))){ //cursor isn't null and element equals elem
counter++; //increment counter
}
else {
return counter; //return counter
}
}
}
Also, note that cursor.getElement().equals(elem) will return a NullPointerException when cursor.getElement() is null. The easiest way to deal with this is probably to write a separate equals method:
boolean equals(E e1, E e2)
{
if (e1 == null)
return e2 == null;
if (e2 == null)
return false;
return e1.equals(e2);
}
Also, presumably Node<E> cursor = tail; makes it point to the end of the list and presumably you want Node<E> cursor = head; instead.
One of the fundamental things that you were missing was a loop. Since you are essentially searching for something, you want to loop through the entire list. Once you run into an element that matches the one that you are searching for, you want to increment the count by 1. Once you have finished looping through the entire list, you want to return that count. So this is my solution. I keep it simple so you could understand:
import java.util.LinkedList;
public class Duplicates<E> extends LinkedList<E> {
public static void main(String[] args) {
Duplicates<String> duplicates = new Duplicates<String>();
duplicates.add("abc");
duplicates.add("def");
duplicates.add("def");
duplicates.add("xyz");
System.out.println(duplicates.duplicateCount("def"));
duplicates.add(null);
duplicates.add("def");
duplicates.add(null);
System.out.println(duplicates.duplicateCount("def"));
System.out.println(duplicates.duplicateCount(null));
}
public int duplicateCount(E element) {
int count = 0;
for (E e : this) {
if (e == element) {
count++;
}
}
return count;
}
}
Output:
2
3
2
I suggest you combine Martin's answer (which tells you how to count the elements) with this, which tell you how to be able to use foreach - you just have to make your SLinkedListExtended implement Iterable, whioch should be something liek the follwoing (you could do this on SLinkedList, but I'm assuming you were told not to alter the code for that one):
public class SLinkedListExtended<E> extends SLinkedList<E> implements Iterable<E> () {
public Iterator<E> iterator() {
final Node<E> itHead = head;
return new Iterator<E>() {
Node<E> current = itHead;
long position = 0;
public boolean hasNext() {
return current != null && position < size;
}
public E next() {
current = current.getNext();
++position;
return current.getElement();
}
public void remove() {
throw new UnsupportedOperationException("Not supported yet.");
}
};
}
};
I can't vouch for all the details, but this should cover most of it. You may also consider using equals instead of ==, but don't forget to check the elements for nullity.
next should only be called if hasNext is true, so it's not a problem if it throws an exception (but it should be a NoSuchElementException to keep in line with the contract).
Implementing Iterable makes your class compatible with the Collections library, hence the support for foreach, but you can use it to do raw iteration by calling iterator, hasNext and next yourself.

Categories