The simplest interface to represent a list is the Iterable
interface.
This interface allows you to iterate over the various elements within the list.
An additional bonus is that when this interface is implemented, you may use an enhanced for-loop to iterate over the elements in your very own LinkedList
.
The Iterable
interface looks like this*:
public interface Iterable<T> {
Iterator<T> iterator();
}
*There are two more methods, but you only need to override this one. (Did we tell you about default implementations yet? Feel free to ignore this tid-bit.)
The one method of Iterable
returns a specific implementation of Iterator
. Which defines two methods:
public interface Iterator<T> {
T next();
boolean hasNext();
}
You could write a normal loop using an iterator:
for (Iterator<T> i=list.iterator(); i.hasNext(); ) {
T current = i.next();
}
But once again, it makes more sense to simply do:
for (T current:list) {
}
Note: Just to make it clear:
Iterable
represents the entire list.Iterator
moves over the elements of the list.
Iterable
interface.Add the interface to the class and start writing the iterable()
method. You will notice that you for now have no idea what you should return. Implement the method by simply returning null
.
Iterator
interface.At the end of the class body, but still within the body of the class declare a new class. Call it MyIterator
if you want.
Note: We expect that your root node is declared as private. This new internal class is an integral part of the entire class and therefore has access to its private fields.
The point of your Iterator
is to traverse over each node of your linked list.
next()
method return the current nodes value, and moves to the next element in the list.hasNext()
method returns true
as long as there is a current node.null
when next()
is called or throw a NoSuchElement
exception.Now that your very own LinkedList
class implements Iterable
confirm its content with a dedicated unittest. I find the following
methods handy, feel free to “borrow” them.
@Test
public void GivenMyOwnList_WhenIterating_AllValuesMatch() {
// This is an example
assertContent(myOwnList, "Item 1", "Item 2", "Item 3", "Item 4");
}
public static <Q> void assertContent(Iterable<Q> iterable, Q... values) {
assertNotNull(iterable);
assertContent(iterable.iterator(), values);
// Or use the built in:
assertIterableEquals(iterable, values);
}
public static <Q> void assertContent(Iterator<Q> iterator, Q... values) {
for (Q value:values) {
assertTrue(iterator.hasNext());
Q actual = iterator.next();
assertEquals(value, actual);
}
assertFalse(iterator.hasNext());
}