1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27public
28class LinkedList<E> {
29
30
31
32
33
34
35
36 protected
37 E info;
38
39 protected
40 LinkedList<E> next;
41
42
43
44
45
46
47
48 protected
49 LinkedList(E info, LinkedList<E> next)
50 {
51 this.info = info;
52 this.next = next;
53 }
54
55
56
57
58
59
60
61
62
63 public static
64 <E> LinkedList<E> mkEmptyList()
65 {
66 return
67 new LinkedList<E>(null, null);
68 }
69
70
71
72
73
74
75 public static
76 <E> LinkedList<E> mkOne(E info)
77 {
78 LinkedList<E> res = mkEmptyList();
79 return
80 res.cons(info);
81 }
82
83
84
85 public
86 LinkedList<E> cons(E info)
87 {
88 return
89 new LinkedList<E>(info, this);
90 }
91
92
93
94 public
95 boolean isEmpty()
96 {
97 return
98 next == null;
99 }
100
101
102
103 public
104 E hd()
105 throws IndexOutOfBoundsException
106 {
107 if ( isEmpty() )
108 throw
109 new IndexOutOfBoundsException("hd of empty list");
110
111 return
112 info;
113 }
114
115
116
117 public
118 LinkedList<E> tl()
119 throws IndexOutOfBoundsException
120 {
121 if ( isEmpty() )
122 throw
123 new IndexOutOfBoundsException("tl of empty list");
124
125 return
126 next;
127 }
128
129
130
131 public
132 int len()
133 {
134 return
135 isEmpty()
136 ? 0
137 : 1 + next.len();
138 }
139
140
141
142 public
143 E at(int i)
144 throws IndexOutOfBoundsException
145 {
146 if ( i < 0 || isEmpty() )
147 throw
148 new IndexOutOfBoundsException("illegal index into linked list");
149
150 return
151 ( i == 0 )
152 ? hd()
153 : next.at(i - 1);
154 }
155
156
157
158 public
159 boolean isIn(E o)
160 {
161 return
162 ! isEmpty()
163 &&
164 ( info.equals(o)
165 ||
166 next.isIn(o) );
167 }
168
169
170
171
172
173
174
175
176 public
177 LinkedList<E> insert(E o)
178 {
179 if ( isIn(o) )
180 return
181 this;
182
183 return
184 cons(o);
185 }
186
187
188
189
190
191
192
193
194 public
195 LinkedList<E> remove(E o)
196 {
197 if ( isEmpty() )
198 return
199 this;
200
201 if ( info.equals(o) )
202 return
203 next;
204
205 next = next.remove(o);
206
207
208
209 return
210 this;
211 }
212
213
214
215 public
216 LinkedList<E> concat(LinkedList<E> l2)
217 {
218 if ( isEmpty() )
219 return
220 l2;
221
222 if ( next.isEmpty() ) {
223 next = l2;
224 } else {
225 next = next.concat(l2);
226 }
227
228 return
229 this;
230 }
231
232
233
234 public
235 LinkedList<E> append(E o)
236 {
237 return
238 concat(mkOne(o));
239 }
240
241
242
243 public
244 String toString()
245 {
246 if ( isEmpty() )
247 return
248 "[]";
249
250 return
251 "[" + info.toString() + next.toString0();
252
253
254 }
255
256 private
257 String toString0()
258 {
259 String s = "";
260 if ( isEmpty() )
261 return
262 "]";
263
264 return
265 "," + info.toString() + next.toString0();
266 }
267
268
269
270
271 public
272 <Result> Result forall(Accumulate <E, Result> ac)
273 {
274 LinkedList<E> l1 = this;
275
276 while ( ! l1.isEmpty() ) {
277 ac.process(l1.info);
278 l1 = l1.next;
279 }
280
281 return
282 ac.getResult();
283 }
284
285
286
287
288 public
289 int len1()
290 {
291
292 return
293 forall(new NoOfElements<E>());
294 }
295
296
297
298
299 public
300 String toString1()
301 {
302 return
303 forall(new ToString <E>("[", ",", "]"));
304 }
305
306
307
308
309
310
311
312
313
314
315 public
316 int len2()
317 {
318 return
319 forall(new LocalNoOfElements <E> ());
320 }
321
322
323
324
325
326 static
327 private
328 class LocalNoOfElements <E>
329 extends Accumulate <E, Integer>
330 {
331 int result = 0;
332
333 public
334 void process(E element)
335 {
336 ++result;
337 }
338
339 public
340 Integer getResult()
341 {
342 return
343 result;
344 }
345 }
346
347
348
349}