class Node { public Object data; public Node next; }
public class LinkedList { private Node first; ... }
public void addFirst(Object element) { Node newNode = new Node(); newNode.data = element; newNode.next = first; first = newNode; }
It is very easy to make mistakes when updating the links. Suppose you had forgotten the last line in the method of the preceding slide:
public void addFirst(Object element) { Node newNode = new Node(); newNode.data = element; newNode.next = first;first = newNode;}
What would happen?
addFirst
would not compile.NullPointerException
would happen whenever addFirst
is called.addFirst
would have no effect on the contents of the linked list.addFirst
would add an element after the first node, not before it.It's your turn. Implement a method addSecond
that adds an element after the first node, not before it. You may assume that the linked list has at least one element.
Make a sketch similar to the one in the book for addFirst
.
Write your name and student ID on your sheet. When prompted, hand it to the front.
Now implement what you just wrote in this program.
What happened?
public class LinkedList { . . . public Object removeFirst() { if (first == null) { throw new NoSuchElementException(); } Object element = first.data; first = first.next; return element; } . . . }
next
, hasNext
, remove
, add
, set
remove
, set
remove
does not remove the element to which the iterator points.next
while (iter.hasNext())
{
String next = iter.next();
if (we do not like next)
iter.remove();
}
removeIf
remove
twice in a row, without a call to next
in between
String next = iter.next(); iter.remove(); // ok iter.remove(); // NOT ok
set
must immediately follow next
:while (iter.hasNext()) { String next = iter.next(); if (we do not like next) iter.set(something better); }
class LinkedListIterator implements ListIterator { private Node position; private Node previous; private boolean isAfterNext; ... }
previous
is needed for removal public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } previous = position; // Remember for remove isAfterNext = true; if (position == null) { position = first; } else { position = position.next; } return position.data; }
hasNext
public boolean hasNext() { if (position == null) { return first != null; } else { return position.next != null; } }
remove
public void remove() { if (!isAfterNext) { throw new IllegalStateException(); } if (position == first) { removeFirst(); } else { previous.next = position.next; } position = previous; isAfterNext = false; }
Suppose we removed the lines
if (!isAfterNext) { throw new IllegalStateException(); }
and
isAfterNext = false;
from the remove
method. What would happen if one called remove
twice in a row?
add
public void add(Object element) { if (position == null) { addFirst(element); position = first; } else // see Paper Question 2 { Node newNode = new Node(); newNode.data = element; newNode.next = position.next; position.next = newNode; position = newNode; } isAfterNext = false; }
I've done a lot of drawing for you. Now it's your turn. You draw up the second scenario of the add
method, as nicely as you can.
Write your name and student ID on your sheet. When prompted, hand it to the front.
Actually, the table from the last slide isn't true for the implementation that we just studied. Which of them is false?
Ok, so let's add a tail reference.
public class LinkedList { private Node first; private Node last; ... }
Now we need to update it in all methods that mutate the list. Here is ListIterator.remove
:
public void remove() { if (!isAfterNext) { throw new IllegalStateException(); } if (position == first) { removeFirst(); } else { previous.next = position.next; } if (___) ___; position = previous; isAfterNext = false; }
What should be filled in for the two ___?