David Farthing
David Farthing

Reputation: 247

Iterator not printing items that clearly exist is LinkedList

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

Answers (1)

Ilya Novoseltsev
Ilya Novoseltsev

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

Related Questions