Ovewriting toString method in deque class using generics - java

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.

Related

Generic LinkedQueue, unable to reach head variable from inner iterator class

I have made my own implementation of a generic Linked Queue for class, it is pretty much finished, here it is:
public class LinkedQueue<T> implements Queue<T> {
//Using head & tail approach.
private myNode<T> head;
private myNode<T> tail;
private int size;
public LinkedQueue(){
this.head = null;
this.tail = head;
this.size = 0;
}
public myNode<T> getterHead(){ //couldn't bring myself to write "get" instead of "getter"
return this.head;
}
#Override
public int size() {
return this.size; //returns number of nodes
}
#Override
public boolean isEmpty() {
return this.head==null;
}
#Override
public void enqueue(T element) {
if(isEmpty()){
this.head = new myNode<T>(element);
this.tail = head;
size++;
}
else{
this.tail.next = new myNode<T>(element);
this.tail = tail.next;
size++;
}
}
#Override
public T dequeue() {
if(isEmpty())throw new NoSuchElementException("This queue is empty");
T returnObj = this.head.data; //saving the data of the first element(head)
//If there are at least 2 nodes, else.
if(head != tail){
this.head = head.getNext();
size--;
}
else{
this.head = null;
this.tail = head;
this.size = 0;
}
return returnObj;
}
#Override
public T first() {
return this.head.data;
}
#Override
public T last() {
return this.tail.data;
}
/* I absolutely can not get past this NullPointerException that is given every time
* I try to use the iterator. It seems that current.next is always null(doesn't point to head properly?).
* HOWEVER, if you change "curr" for "head", it works. */
#Override
public Iterator<T> iterator() {
return new GenericIterator();
}
private class GenericIterator implements Iterator<T>{
public myNode<T> curr = head;
public boolean hasNext() {
return (head != null && head.next != null);
}
public T next() {
T tmp = head.data; //saving current in a temporary node because we are changing the value of current in the next line
if(hasNext()){
head = head.next;
}
return tmp;
}
}
private class myNode<T> { //parameter type T hiding type T
public T data; //The generic data the nodes contain
public myNode<T> next; //Next node
//Node constructor
public myNode(T nData) {
this.data = nData;
this.next = null;
}
public myNode<T> getNext(){
return this.next;
}
}
}
Here is the part that is giving me trouble:
/* I absolutely can not get past this NullPointerException that is given every time
* I try to use the iterator. It seems that current.next is always null(doesn't point to head properly?).
* HOWEVER, if you change "curr" for "head", it works. */
#Override
public Iterator<T> iterator() {
return new GenericIterator();
}
private class GenericIterator implements Iterator<T>{
public myNode<T> curr = head; //doesn't work with getter either.
//public myNode<T> curr = getterHead();
public boolean hasNext() {
return (curr != null && curr.next != null);
}
public T next() {
T tmp = curr.data; //NPE HERE!
if(hasNext()){
curr = curr.next;
}
return tmp;
}
}
What I have tried is getters/setters and triple-checking every other method(they work). What seems to be the problem is that when I assign curr = head, it seems that the properties from myNode do not come with.
While head.next works fine, curr.next == null, even curr.data == null while head.data works.
I've tried with public properties and printing LinkedQueue.head.next etc, it works fine.
Stacktrace:
Exception in thread "main" java.lang.NullPointerException
at dk222gw_lab4.Queue.LinkedQueue$GenericIterator.next(LinkedQueue.java:101)
at dk222gw_lab4.Queue.LinkedQueueMain.main(LinkedQueueMain.java:17)
Where line 101 & 17 are:
T tmp = curr.data; //node property .data & .next are null.
System.out.println(it.next()); //LinkedQueueMain.java(not included in post), both it.next() and it.hasNext() produce this NPE.

Confused about choosing a loop to iterate a linked list

My problem is in the add method. I think I know what I want it to do but I can't figure out what type of loop I should use to look through the list. As you can see I started to make a if else loop but I couldn't figure out what I should use as the counter. I'm pretty sure I have the right logic in dealing with the add but I feel like I'm not quite there yet. I was thinking of using compareTo in some fashion.
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node topNode;
private class Node
{
private E data;
private Node nextNode;
public Node(E data)
{
this.data = data;
nextNode = null;
}
}
public OrderedLinkedList()
{
topNode = null;
}
public boolean empty()
{
if(topNode == null)
return true;
return false;
}
public String toString()
{
String myString = "";
Node nextNode = topNode;
while(nextNode != null)
{
myString = topNode + " -> " + nextNode;
nextNode = topNode.nextNode;
}
return myString;
}
public void add(E data)
{
Node myNode = new Node(data);
Node priorNode = topNode;
Node currentNode = topNode;
if(___)
{
priorNode = currentNode;
currentNode = currentNode.nextNode;
}
else
{
priorNode.nextNode = myNode;
myNode.nextNode = currentNode;
}
}
}
Since you don't typically know the length of a linked list until you've walked down it, the usual thing would be to use a while loop (as you've done in your toString() method)
Perhaps using a doubly linked list would be more beneficial. Consider the following alterations to your class:
import java.util.*;
public class OrderedLinkedList<E extends Comparable<E>>
{
private Node head;
private Node tail;
private class Node
{
private E data;
private Node nextNode;
private Node prevNode;
public Node(E data)
{
this.data = data;
nextNode = null;
prevNode = null;
}
public void setNext(Node node)
{
this.nextNode = node;
}
public Node getNext()
{
return this.nextNode;
}
public void setPrev(Node node)
{
this.prevNode = node;
}
public Node getPrev()
{
return this.prevNode;
}
public E getData()
{
return this.data;
}
public int compareTo(Node that) {
if(this.getData() < that.getData())
{
return -1;
}
else if(this.getData() == that.getData()
{
return 0;
}
else
{
return 1;
}
}
}
public OrderedLinkedList()
{
head = new Node(null);
tail = new Node(null);
head.setNext(tail);
tail.setPrev(head);
}
public boolean empty()
{
if(head.getNext() == tail)
{
return true;
}
return false;
}
public void add(E data) {
Node tmp = new Node(data);
if(this.empty()) {
this.addNodeAfterNode(tmp, head);
} else {
Node that = head.getNext();
// this while loop iterates over the list until finding the correct
// spot to add the new node. The correct spot is considered to be
// when tmp's data is >= that's data, or the next node after 'that'
// is tail. In which case the node is added to the end of the list
while((tmp.compareTo(that) == -1) && (that.getNext() != tail)) {
that = that.getNext();
}
this.addNodeAfterNode(tmp, that);
}
}
private void addNodeAfterNode(Node addNode, Node afterNode)
{
addNode.setNext(afterNode.getNext());
afterNode.getNext().setPrev(addNode);
afterNode.setNext(addNode);
addNode.setPrev(afterNode);
}
}

Iterator method?

I'm implementing a list interface with links but since "ListADT" implements the Iterable interface. So, I have to have a method that produces an iterator which I'm not sure how to do. I tried using it as it is now and when I created an object for the linkedlist, and then call the iterator() method, I get an overflow. I know the method is supposed to produce an Iterator object but not sure how.
import java.util.Iterator;
public class LinkedList<T> implements ListADT<T>
{
protected int count;
protected LinearNode <T> head, tail;
private int modCount;
public LinkedList()
{
count =0;
head = tail= null;
}
public T removeFirst()
{
T result = head.getElement();
head = head.getNext();
count--;
return result;
}
public T removeLast()
{
// THROW EMPTY EXCEPTION
T result;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while(!current.equals(tail))
{
previous = current;
current = current.getNext();
}
result = tail.getElement();
tail = previous;
tail.setNext(null);
count--;
return result;
}
public T remove(T element)
{
// throw exception
boolean found = false;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while (current != null && !found)
{
if(element.equals(current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
if (!found)
{
}
else if (current.equals(head))
{
head = current.getNext();
}
else if(current.equals(tail))
{
tail = previous;
tail.setNext(null);
}
else
previous.setNext(current.getNext());
}
count --;
return current.getElement();
}
public T first()
{
return head.getElement();
}
public T last()
{
return tail.getElement();
}
public boolean contains(T target)
{
boolean found = false;
LinearNode <T> previous = null;
LinearNode <T> current = head;
while (current != null && !found)
{
if(target.equals(current.getElement()))
found = true;
else
{
previous = current;
current = current.getNext();
}
}
return found;
}
public boolean isEmpty()
{
boolean result = false;
if( head == null && tail ==null)
{
result = true;
}
return result;
}
public int size()
{
return count;
}
public Iterator<T> iterator()
{
return this.iterator();
}
public String toString()
{
LinearNode <T> current = head;
String result ="";
String line = "";
int loopCount=0;
while(current != null)
{
loopCount++;
line = loopCount + "> " + (String) current.getElement() + "\n";
result = result + line;
current = current.getNext();
}
return result;
}
}
Your problem
You're getting an overflow because the line this.iterator() in your function public Iterator<T> iterator(), calls, you guessed it public Iterator<T> iterator().
Approach 1: The lazy way
If you don't plan on using the iterator for this class, (this looks like a programming assignment) you can always do the super super lazy.
public Iterator<T> iterator() {
throw new UnsupportedOperationException("Pffffft you don't need no iterator");
}
This approach is listed here just for completeness. Seeing as your linked list has no other way to access a random element in the middle without removing everything in front or behind it, I recommend you:
DO NOT DO THIS
Approach 2: The Correct Way
The thing about iterators is that they do a specific subset of what a list does, namely hasNext(), next(), and remove(). If you're unsure what those three methods do, I suggest you take a look at http://docs.oracle.com/javase/7/docs/api/java/util/Iterator.html
You should create a public inner class.
public class LinkedList<T> implements ListADT<T> {
... stuff
private class MyIterator<T> implements Iterator<T> {
//It's best practice to explicitly store the head in the iterator
private LinearNode<T> head;
public MyIterator<T>(LinkedList<T>) {
...
}
#Override
public boolean hasNext() {
...
}
#Override
public T next() {
...
}
#Override
public void remove() {
...
}
}
public Iterator<T> iterator() {
return new MyIterator<T>(this);
}
}
Now if you're really clever, you can rewrite the rest of your code based on the iterator. Note:
DO THIS

Linked List Recursive removeAll method

I'm trying to define a recursive method that removes all instances in the singly-linked list that are equal to the target value. I defined a remove method and an accompanying removeAux method. How can I change this so that if the head needs to be removed, the head is reassigned as well? Here is what I have so far:
public class LinkedList<T extends Comparable<T>> {
private class Node {
private T data;
private Node next;
private Node(T data) {
this.data = data;
next = null;
}
}
private Node head;
public LinkedList() {
head = null;
}
public void remove(T target) {
if (head == null) {
return;
}
while (target.compareTo(head.data) == 0) {
head = head.next;
}
removeAux(target, head, null);
}
public void removeAux(T target, Node current, Node previous) {
if (target.compareTo(current.data) == 0) {
if (previous == null) {
head = current.next;
} else {
previous.next = current.next;
}
current = current.next;
removeAux(target, current, previous); // previous doesn't change
} else {
removeAux(target, current.next, current);
}
}
I prefer to pass a reference to the previous when you remove to switch previous to the next something like this
public void remove(T target){
removeAux(target,head, null);
}
public void removeAux(T target, Node current, Node previous) {
//case base
if(current == null)
return;
if (target.compareTo(current.data) == 0) {
if (previous == null) {
// is the head
head = current.next;
} else {
//is not the head
previous.next = current.next;
}
current = current.next;
removeAux(target, current, previous); // previous doesn't change
} else {
removeAux(target, current.next, current);
}
}
Check this answer graphically linked list may help you to think how to implement it.
If this for training is good but you can do in iterative way.
You could try to fashion your function so that it works like this.
head = removeAux(target, head); // returns new head
A neat trick I learn't from Coursera's Algorithms classes.
The rest of the code is as follows.
public void removeAux(T target, Node current) {
//case base
if(current == null)
return null;
current.next = removeAux(target, current.next);
return target.compareTo(current.data) == 0? current.next: current; // the actual deleting happens here
}

Java LinkedList Program [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
So i am trying to compile my LinkedList for a program that i have created and it is coming back with errors that i feel are really errors (if that makes since). I am wondering if anyone can look at this and put in their thoughts of why i might be getting errors when i compile and if they have any suggestions on what i should do to get rid of them:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class LinkedListDS<E> implements ListADT<E> {
class Node<E> {
E data;
Node<E> next;
public Node(E data) {
this.data = data;
next = null;
}
}
private Node<E> head, tail;
private int currentSize;
public LinkedListDS() {
head = tail = null;
currentSize = 0;
}
public void addFirst(E obj) {
if(head == null)
head = tail = newNode;
else {
newNode.next = head;
head = newNode;
}
currentSize++;
}
// Adds the Object obj to the end of the list
public void addLast(E o) {
if(head == null)
head = newNode;
tail = newNode;
currentSize++;
return;
{
tail.next = newNode;
tail = newNode;
currentSize++;
}
}
// Removes the first Object in the list and returns it.
// Returns null if the list is empty.
public E removeFirst() {
if(head == null)
return null;
E tmp = head.data;
head = head.next;
{
if (head == null)
tail = null;
currentSize++;
return tmp;
}
}
// Removes the last Object in the list and returns it.
// Returns null if the list is empty.
public E removeLast() {
Node<E> previous = null;
Node<E> current = head;
if (current == null)
return null;
while(current.next != null) {
previous = current;
current = current.next;
}
if(previous = null)
return removeFirst;
previous.next = null;
tail = previous;
currentSize--;
return current.data;
}
// Returns the first Object in the list, but does not remove it.
// Returns null if the list is empty.
public E peekFirst() {
if(head == null)
return null;
return head.data;
}
// Returns the last Object in the list, but does not remove it.
// Returns null if the list is empty.
public E peekLast() {
if(tail == null)
return null;
return tail.data;
}
// Removes the specific Object obj from the list, if it exists.
// Returns true if the Object obj was found and removed, otherwise false
public boolean remove(E obj) {
if(head == null)
return false;
{
if(head.data.equals(obj))
head = head.next;
return true;
}
Node<E> current = head;
while(current.next != null)
{
if(current.next.data.equals(obj))
{
current.next = current.next.next;
return true;
}
current - current.next;
}
currentSize--;
return false,
}
}
// The list is returned to an empty state.
public void makeEmpty() {
head = tail = null;
currentSize = 0;
// Returns true if the list contains the Object obj, otherwise false
public boolean contains(E obj) {
Node<E> current = head;
while(current != null)
{
if(current.data.equals(obj))
{
return true;
}
current - current.next;
}
return false;
}
// Returns true if the list is empty, otherwise false
public boolean isEmpty() {
return = null;
}
// Returns true if the list is full, otherwise false
public boolean isFull() {
return false;
}
// Returns the number of Objects currently in the list.
public int size() {
return currentSize;
}
public iterator<E> iterator() {
return new iterator;
}
class IteratorHelper implements Iterator<E> {
Node<E> iteratorPointer
public IteratorHelper() {
iteratorPointer = head;
}
public boolean hasNext() {
return iteratorPointer != null;
}
public E next() {
if(!hasNext())
throw new NoSuchElementException();
E tmp = iteratorPointer.data;
iteratorPointer = iteratorPointer.next;
return tmp;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
Also, is there a way that i can make this code more simpler to read, understand, not as long but yet still have the same task to complete? Please feel free to share.
You have defined an interface and are using it as class..
public interface LinkedListDS<E> implements ListADT<E> {
Problems in above declaration: -
Interface does not implement other interface, they extend, just like a class extends another class..
Interface does not define methods and constructors
So, you wanted to use a class actually..
Change the above declaration to: -
public class LinkedListDS<E> implements ListADT<E> {
Also, you haven't closed your iterator method..
public iterator<E> iterator() {
return new iterator;
Add a closing brace.. Actually, you have so many of them... Re-indent your code to check the matching braces.. That is one major problem you face when you are not indenting the code..

Categories