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