1
2
3
4 package jwutil.collections;
5
6 import java.lang.reflect.Array;
7 import java.util.AbstractList;
8 import java.util.Collection;
9 import java.util.Iterator;
10 import java.util.List;
11 import java.util.ListIterator;
12 import java.util.NoSuchElementException;
13
14 /***
15 * A list which is two lists appended together.
16 *
17 * @author John Whaley
18 * @version $Id: AppendList.java 1934 2004-09-27 22:42:35Z joewhaley $
19 */
20 public class AppendList implements List {
21
22 protected List l1, l2;
23
24 public AppendList(List l1, List l2) {
25 this.l1 = l1; this.l2 = l2;
26 }
27
28
29
30
31 public int size() {
32 return l1.size() + l2.size();
33 }
34
35
36
37
38 public void clear() {
39 l1.clear(); l2.clear();
40 }
41
42
43
44
45 public boolean isEmpty() {
46 return l1.isEmpty() && l2.isEmpty();
47 }
48
49 private static final boolean USE_ARRAYCOPY = false;
50
51
52
53 public Object[] toArray() {
54 int n = size();
55 Object[] result = new Object[n];
56 l1.toArray(result); n = l1.size();
57 if (USE_ARRAYCOPY) {
58 System.arraycopy(l2.toArray(), 0, result, n, l2.size());
59 } else {
60 for (Iterator i=l2.iterator(); i.hasNext(); ) {
61 result[n++] = i.next();
62 }
63 }
64 return result;
65 }
66
67
68
69
70 public Object get(int index) {
71 int n = l1.size();
72 if (index < n) return l1.get(index);
73 else return l2.get(index-n);
74 }
75
76
77
78
79 public Object remove(int index) {
80 int n = l1.size();
81 if (index < n) return l1.remove(index);
82 else return l2.remove(index-n);
83 }
84
85
86
87
88 public void add(int index, Object element) {
89 int n = l1.size();
90 if (index < n) l1.add(index, element);
91 else l2.add(index-n, element);
92 }
93
94
95
96
97 public int indexOf(Object o) {
98 int n = l1.indexOf(o);
99 if (n != -1) return n;
100 n = l2.indexOf(o);
101 if (n != -1) return l1.size()+n;
102 return -1;
103 }
104
105
106
107
108 public int lastIndexOf(Object o) {
109 int n = l2.lastIndexOf(o);
110 if (n != -1) return n+l1.size();
111 return l1.lastIndexOf(o);
112 }
113
114
115
116
117 public boolean add(Object o) {
118 return l2.add(o);
119 }
120
121
122
123
124 public boolean contains(Object o) {
125 return l1.contains(o) || l2.contains(o);
126 }
127
128
129
130
131 public boolean remove(Object o) {
132 boolean result = l1.remove(o);
133 if (result == true) return true;
134 return l2.remove(o);
135 }
136
137
138
139
140 public boolean addAll(int index, Collection c) {
141 int n = l1.size();
142 if (index < n) return l1.addAll(index, c);
143 else return l2.addAll(index-n, c);
144 }
145
146
147
148
149 public boolean addAll(Collection c) {
150 return l2.addAll(c);
151 }
152
153
154
155
156 public boolean containsAll(Collection c) {
157 for (Iterator i=c.iterator(); i.hasNext(); ) {
158 if (!this.contains(i.next()))
159 return false;
160 }
161 return true;
162 }
163
164
165
166
167 public boolean removeAll(Collection c) {
168 boolean result = false;
169 if (l1.removeAll(c)) result = true;
170 if (l2.removeAll(c)) result = true;
171 return result;
172 }
173
174
175
176
177 public boolean retainAll(Collection c) {
178 boolean result = false;
179 if (l1.retainAll(c)) result = true;
180 if (l2.retainAll(c)) result = true;
181 return result;
182 }
183
184
185
186
187 public Iterator iterator() {
188 return new AppendIterator(l1.iterator(), l2.iterator());
189 }
190
191
192
193
194 public List subList(final int fromIndex, final int toIndex) {
195 return new SubList(this, fromIndex, toIndex);
196 }
197
198 static class SubList extends AbstractList {
199 private List l;
200 private int offset;
201 private int size;
202
203 SubList(List list, int fromIndex, int toIndex) {
204 if (fromIndex < 0)
205 throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
206 if (toIndex > list.size())
207 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
208 if (fromIndex > toIndex)
209 throw new IllegalArgumentException("fromIndex(" + fromIndex +
210 ") > toIndex(" + toIndex + ")");
211 l = list;
212 offset = fromIndex;
213 size = toIndex - fromIndex;
214 }
215
216 public Object set(int index, Object element) {
217 rangeCheck(index);
218 return l.set(index+offset, element);
219 }
220
221 public Object get(int index) {
222 rangeCheck(index);
223 return l.get(index+offset);
224 }
225
226 public int size() {
227 return size;
228 }
229
230 public void add(int index, Object element) {
231 if (index<0 || index>size)
232 throw new IndexOutOfBoundsException();
233 l.add(index+offset, element);
234 size++;
235 }
236
237 public Object remove(int index) {
238 rangeCheck(index);
239 Object result = l.remove(index+offset);
240 size--;
241 return result;
242 }
243
244 public boolean addAll(Collection c) {
245 return addAll(size, c);
246 }
247
248 public boolean addAll(int index, Collection c) {
249 if (index<0 || index>size)
250 throw new IndexOutOfBoundsException(
251 "Index: "+index+", Size: "+size);
252 int cSize = c.size();
253 if (cSize==0)
254 return false;
255
256 l.addAll(offset+index, c);
257 size += cSize;
258 return true;
259 }
260
261 public Iterator iterator() {
262 return SubList.this.listIterator();
263 }
264
265 public ListIterator listIterator(final int index) {
266 if (index<0 || index>size)
267 throw new IndexOutOfBoundsException(
268 "Index: "+index+", Size: "+size);
269
270 return new ListIterator() {
271 private ListIterator i = l.listIterator(index+offset);
272
273 public boolean hasNext() {
274 return nextIndex() < size;
275 }
276
277 public Object next() {
278 if (hasNext())
279 return i.next();
280 else
281 throw new NoSuchElementException();
282 }
283
284 public boolean hasPrevious() {
285 return previousIndex() >= 0;
286 }
287
288 public Object previous() {
289 if (hasPrevious())
290 return i.previous();
291 else
292 throw new NoSuchElementException();
293 }
294
295 public int nextIndex() {
296 return i.nextIndex() - offset;
297 }
298
299 public int previousIndex() {
300 return i.previousIndex() - offset;
301 }
302
303 public void remove() {
304 i.remove();
305 size--;
306 }
307
308 public void set(Object o) {
309 i.set(o);
310 }
311
312 public void add(Object o) {
313 i.add(o);
314 size++;
315 }
316 };
317 }
318
319 public List subList(int fromIndex, int toIndex) {
320 return new SubList(this, fromIndex, toIndex);
321 }
322
323 private void rangeCheck(int index) {
324 if (index<0 || index>=size)
325 throw new IndexOutOfBoundsException("Index: "+index+
326 ",Size: "+size);
327 }
328 }
329
330
331
332
333 public ListIterator listIterator() {
334 return new AppendListIterator(l1.listIterator(), l2.listIterator());
335 }
336
337
338
339
340 public ListIterator listIterator(int index) {
341 int n = l1.size();
342 if (index < n)
343 return new AppendListIterator(l1.listIterator(index), l2.listIterator());
344 else
345 return l2.listIterator(index-n);
346 }
347
348
349
350
351 public Object set(int index, Object element) {
352 int n = l1.size();
353 if (index < n)
354 return l1.set(index, element);
355 else
356 return l2.set(index-n, element);
357 }
358
359
360
361
362 public Object[] toArray(Object[] result) {
363 int n = size();
364 if (result.length < n) {
365 result = (Object[]) Array.newInstance(result.getClass().getComponentType(), n);
366 }
367 l1.toArray(result); n = l1.size();
368 if (USE_ARRAYCOPY) {
369 System.arraycopy(l2.toArray(), 0, result, n, l2.size());
370 } else {
371 for (Iterator i=l2.iterator(); i.hasNext(); ) {
372 result[n++] = i.next();
373 }
374 }
375 return result;
376 }
377
378 }