Reputation: 247
I am writing a class that maintains a Deque (that is it can be added to at the head or the tail of the LinkedList). I created a test using a main class that adds one item to the head and one to the tail, and it appears they exist because the size = 2 and prints, but the actual Strings I added don't print. Why?
This is my code:
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
*
* @author David Farthing
*/
public class Deque<Item> implements Iterable<Item> {
//fields for Deque class
private LinkedList deque;
private int numNodes;
//constructor
public Deque(){
deque = new LinkedList();
numNodes = 0;
}
private class DequeIterator implements Iterator<Item> {
private Node<Item> curr;
public DequeIterator(Node<Item> head) {
curr = head;
}
@Override
public boolean hasNext(){return curr != null;}
@Override
public void remove(){ throw new UnsupportedOperationException();}
@Override
public Item next() {
if(!hasNext()) throw new NoSuchElementException();
Item item = curr.data;
curr = curr.next;
return item;
}
} //end DequeIterator
//inner class to implement a doubly linked list for the deque
private class LinkedList {
Node head;
Node tail;
private LinkedList(){
head = null;
tail = null;
}
private Node getHead(){
return head;
}
private Node getTail(){
return tail;
}
}//end inner class Linked List
//inner class to implement a Node for the LinkedList
private class Node<Item>{
private Item data;
private Node<Item> next; //connection to the next node in the list
private Node<Item> prev; //connection to the previous node in the list
private Node(Item data){
this.data = data;
next = null;
prev = null;
}
private Item getData(){
return data;
}
private Node getNext(){
return next;
}
private Node getPrev(){
return prev;
}
}//end inner class Node
//add item to end
public void addLast(Item item){
Node h = deque.getHead();
Node t = deque.getTail();
//if list is empty
if(h==null && t==null){
h = new Node(item);
t = new Node(item);
h.next = t;
t.prev = h;
}
//if there is only one item in list
else if(h==t){
t = new Node(item);
t.prev = h;
h.next = t;
}
else {
//get the node previous to tail
Node oldLast = t.getPrev();
Node newLastNode = new Node(item);
newLastNode.next = t; //the new last node is pointing to tail
oldLast.next = newLastNode; //the previous last node which temp is
//pointing to now points to new last node
}
numNodes++;
}
//remove and return item from front
public Item removeFirst(){
Node h = deque.getHead();
//get Item data from first node in list; uses convert to turn Object
//data into Item data
Item first = convert(h.next.getData());
Node second = h.next.next; //second item in list
h.next = second; //head now points to second item
second.prev = h; //second item points back to head
numNodes--;
return first;
}
//remove and return item from end
public Item removeLast(){
//get the node previous to tail
Node lastNode = deque.getTail().prev;
//get the data from the last node; uses convert to turn Object into Item
Item last = convert(lastNode.getData());
Node t = deque.getTail();//get the tail itself
t.prev = lastNode.prev; //make the tail point back to the
//node previous to the last
numNodes--; //decrement the number of nodes
return last;
}
//return an Iterator over the items from front to end
@Override
public Iterator<Item> iterator(){
Node h = deque.getHead();
return new DequeIterator(h);
}
//convert any object to Item type
private Item convert(Object o){
return (Item) o;
}
//is the Deque empty
public boolean isEmpty(){
if(numNodes == 0) return true;
else return false;
}
//return the number of items in Deuque
public int size(){
return numNodes;
}
//add item to front
public void addFirst(Item item){
Node h = deque.getHead();
if(h == null) {
h = new Node(item);
Node t = deque.getTail();
t = new Node(item);
h.next = t;
t.prev = h;
numNodes++;
}
else {
Node temp = new Node(item); //create new node containing item
temp.next = h.next; //have temp point to the successor to
//head
h.next.prev = temp; //prev of first item now points to temp
h.next = temp; //successor of head is now the new node
temp.prev = h; //the previous pointer now points to h
numNodes++;
}
}
//unit test
public static void main(String[] args){
Deque myList = new Deque();
String f = "first";
String l = "last";
myList.addFirst(f);
myList.addLast(l);
Iterator itr = myList.iterator();
while(itr.hasNext()) {
StdOut.print(itr.next() + " ");
}
StdOut.println("Number of nodes: " + myList.size());
}// end main
}//end class Deque
The output of printing the Deque (LinkedList) is:
run: Number of nodes: 2
Question: Why doesn't the iterator in the while loop print out the strings "first" and "last"?
Upvotes: 0
Views: 339
Reputation: 1873
The reason it doesn't work is that you are not actually putting anything in your list.
When addFirst
is called it doesn't set deque.head
or deque.tail
.
That version will work:
public void addFirst(Item item){
Node h = deque.getHead();
if(h == null) {
h = new Node(item);
Node t = deque.getTail();
t = new Node(item);
h.next = t;
t.prev = h;
numNodes++;
deque.head = h;
deque.tail = t;
}
But I question the need to implement your own Deque. Is it some test exercise? JDK includes java.util.LinkedList
which is a Deque.
Upvotes: 1