SE450: A Linked List: External Iterator [1/25] |
This is an external iterator over a linked list.
Here we use a null object or sentinel to mark the end of the list. (This is a degenerate composite.)
This means that we can sensibly ask an empty list for an
iterator. We cannot do this if the empty list is
represented by null
.
file:iterator/listone/Main.java [source] [doc-public] [doc-private]
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package iterator.listone; import java.util.NoSuchElementException; /* public */ interface List { public Iterator newIterator(); } /* public */ class ListF { private ListF() {} public static final List nil = new Nil(); /* Singleton */ public static final List cons(int hd, List tl) /* Factory */ { return new Cons(hd, tl); } } /* public */ interface Iterator { public boolean hasNext(); public int next(); } /* ************************************************************************* * List classes. ************************************************************************* */ class Nil implements List { Nil() {} public String toString() { return "nil"; } public Iterator newIterator() { return new NullIterator(); } } class Cons implements List { final int hd; final List tl; Cons(int hd, List tl) { this.hd = hd; this.tl = tl; } public String toString() { return hd + "::" + tl.toString(); } public Iterator newIterator() { return new ListIterator(this); } } class NullIterator implements Iterator { NullIterator() { } public boolean hasNext() { return false; } public int next() { throw new NoSuchElementException(); } } class ListIterator implements Iterator { private List node; ListIterator(List node) { this.node = node; } public boolean hasNext() { return node != ListF.nil; } public int next() { if (! hasNext()) throw new NoSuchElementException(); int result = ((Cons)node).hd; node = ((Cons)node).tl; return result; } } /* ************************************************************************* * A test case. ************************************************************************* */ public class Main { public static void main(String[] args) { List test = ListF.cons(1, ListF.cons(2, ListF.cons(3, ListF.nil))); System.out.println(test); int sum=0; for (Iterator i = test.newIterator(); i.hasNext(); ) sum += i.next(); System.out.println(sum); List rev=ListF.nil; for (Iterator i = test.newIterator(); i.hasNext(); ) rev = ListF.cons(i.next(),rev); System.out.println(rev); } }
Note that the attributes must be package private so that the external iterator can access them.