Deque Class Implementation and Testing CheckList 1. Should head

D e q u e C la s s Im p le m e n ta tion a n d Te s t in g C h e c k Lis t
1. Should head and tail be set to null initially?
No! Once head and tail members of Deque have been initialized, they should never be
null! Even for an empty Deque, head and tail should reference two "bookend" Nodes.
After these two Nodes are created in the Deque constructor, they are never deleted and
head and tail will continue to reference these same two Nodes no matter how many
items are added or removed from the Deque.
2. If the Deque is empty and x is added by calling addFirst(x), should head point
to x?
No and No! The x passed to addFirst is a data item, not a Node. So the first "No" is
because head must point to a Node, not a data item. The addFirst method has to create a
new Node with x as the data member of that Node.
The second "No" is because head should not point to a Node containing acutal items
inserted in the Deque. The head Node always points to a "bookend" Node that is before
any Deque items.
So what should point to the first item? Answer: head.next
3. Since head and tail are "bookend" Nodes and the actual items are in Nodes
between these two Nodes, what is the point of using head and tail?
Every Node containing an actual item will be guaranteed to be between two Nodes. So
the prev and next members will never be null for a Node containing an actual item (that
is, for all Nodes between head and tail).
This means that the statements for addFirst when the Deque is empty can be the same
as for when it is non-empty. You don't have to have separate code for the "boundary"
case of an empty list. Why? In both cases addFirst simply adds the new Node just after
the head Node.
Without the "bookend" Nodes, head and tail, you would need to check whether the
reference to the first Node was null or not and write different code for the two cases.
The "bookend" Nodes also allow the other add and remove methods to avoid having to
write different code for "boundary" cases.
4. Shouldn't the Node class defined inside Deque be public?
No! The public methods are for the client applications that may use the Deque class. If
a client application declares a Deque of Strings:
public static void main(String[] args) {
Deque<String> dq = new Deque<String>();
dq.addFirst("A");
dq.addLast("B");
String s = dq.removeFirst(); // s gets "A"
...
}
the client application is only concerned with inserting and removing Strings. The client
knows nothing about the Node type.
The Node type is only for the implementation of the public methods and only the Deque
class should be able to access and use Nodes.
5. Ok, I see that the first item is at head.next, but I think my addFirst is not correct
because the prev and next members of the head and the first item Node are not
being set correctly. Any suggestions?
You can declare a local Node variable in addFirst to point to the first item Node:
public void addFirst(E x) {
Node p = head.next;
...
Notice that this doesn't create new Node. The variable p simply saves a reference to the
first item Node.
Create a new Node with x as the data and assign this to another local Node variable,
say tmp.
How you have 3 Node references: head, tmp, and p. The addFirst method should now
change the approriate prev and next links to insert tmp after head and before p. There are
4 links that must be set.
The variables tmp and p go away when addFirst returns, but the new Node will be
safely linked into the list.
6. I'm stuck on how to implement the iterator() method. It needs to return some
object of type Iterator<E>. But that type is an interface. So how do a create such
an object?
You need to write a class that implements Iterator<E>.
This should be a second private inner class of Deque. Since it is private the name
doesn't matter, but you might name it DequeIterator.
7. Ok, the DequeIterator class should implement the Iterator<E> interface. So
that tells me what the public methods of my DequeIterator should be, but what
should the data member(s) be to represent a DequeIterator value?
An iterator allows accessing the elements of a collection (a Deque in this case) one at a
time from the first to the last.
Since the Deque is a sequence of Nodes, an iterator can be represented by a reference
to the current Node in the Deque, starting with the first one.
Note 1: The iterator next() method returns the data from the current Node, not the
Node itself. But current needs to reference the Node in order to be able to update to
the next Node.
8. I'm trying to write the hasNext() method for my private DequeIterator class and
I'm checking to see if currrent is null? But that doesn't seem to work. Any idea
why?
The next link of the last actual data item is NOT null. The Node after the last actual
item is tail. If current is equal to tail, it is already past the last item and hasNext()
should return false.