View Javadoc

1   // AppendList.java, created Fri May 26 23:58:36 2003 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
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      /* (non-Javadoc)
29       * @see java.util.List#size()
30       */
31      public int size() {
32          return l1.size() + l2.size();
33      }
34  
35      /* (non-Javadoc)
36       * @see java.util.List#clear()
37       */
38      public void clear() {
39          l1.clear(); l2.clear();
40      }
41  
42      /* (non-Javadoc)
43       * @see java.util.List#isEmpty()
44       */
45      public boolean isEmpty() {
46          return l1.isEmpty() && l2.isEmpty();
47      }
48  
49      private static final boolean USE_ARRAYCOPY = false;
50      /* (non-Javadoc)
51       * @see java.util.List#toArray()
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      /* (non-Javadoc)
68       * @see java.util.List#get(int)
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      /* (non-Javadoc)
77       * @see java.util.List#remove(int)
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      /* (non-Javadoc)
86       * @see java.util.List#add(int, java.lang.Object)
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      /* (non-Javadoc)
95       * @see java.util.List#indexOf(java.lang.Object)
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     /* (non-Javadoc)
106      * @see java.util.List#lastIndexOf(java.lang.Object)
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     /* (non-Javadoc)
115      * @see java.util.List#add(java.lang.Object)
116      */
117     public boolean add(Object o) {
118         return l2.add(o);
119     }
120 
121     /* (non-Javadoc)
122      * @see java.util.List#contains(java.lang.Object)
123      */
124     public boolean contains(Object o) {
125         return l1.contains(o) || l2.contains(o);
126     }
127 
128     /* (non-Javadoc)
129      * @see java.util.List#remove(java.lang.Object)
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     /* (non-Javadoc)
138      * @see java.util.List#addAll(int, java.util.Collection)
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     /* (non-Javadoc)
147      * @see java.util.List#addAll(java.util.Collection)
148      */
149     public boolean addAll(Collection c) {
150         return l2.addAll(c);
151     }
152 
153     /* (non-Javadoc)
154      * @see java.util.List#containsAll(java.util.Collection)
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     /* (non-Javadoc)
165      * @see java.util.List#removeAll(java.util.Collection)
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     /* (non-Javadoc)
175      * @see java.util.List#retainAll(java.util.Collection)
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     /* (non-Javadoc)
185      * @see java.util.List#iterator()
186      */
187     public Iterator iterator() {
188         return new AppendIterator(l1.iterator(), l2.iterator());
189     }
190 
191     /* (non-Javadoc)
192      * @see java.util.List#subList(int, int)
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     /* (non-Javadoc)
331      * @see java.util.List#listIterator()
332      */
333     public ListIterator listIterator() {
334         return new AppendListIterator(l1.listIterator(), l2.listIterator());
335     }
336 
337     /* (non-Javadoc)
338      * @see java.util.List#listIterator(int)
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     /* (non-Javadoc)
349      * @see java.util.List#set(int, java.lang.Object)
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     /* (non-Javadoc)
360      * @see java.util.List#toArray(java.lang.Object[])
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 }