001 /*
002 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package java.util;
027
028 /**
029 * This class provides a skeletal implementation of the {@link List}
030 * interface to minimize the effort required to implement this interface
031 * backed by a "random access" data store (such as an array). For sequential
032 * access data (such as a linked list), {@link AbstractSequentialList} should
033 * be used in preference to this class.
034 *
035 * <p>To implement an unmodifiable list, the programmer needs only to extend
036 * this class and provide implementations for the {@link #get(int)} and
037 * {@link List#size() size()} methods.
038 *
039 * <p>To implement a modifiable list, the programmer must additionally
040 * override the {@link #set(int, Object) set(int, E)} method (which otherwise
041 * throws an {@code UnsupportedOperationException}). If the list is
042 * variable-size the programmer must additionally override the
043 * {@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods.
044 *
045 * <p>The programmer should generally provide a void (no argument) and collection
046 * constructor, as per the recommendation in the {@link Collection} interface
047 * specification.
048 *
049 * <p>Unlike the other abstract collection implementations, the programmer does
050 * <i>not</i> have to provide an iterator implementation; the iterator and
051 * list iterator are implemented by this class, on top of the "random access"
052 * methods:
053 * {@link #get(int)},
054 * {@link #set(int, Object) set(int, E)},
055 * {@link #add(int, Object) add(int, E)} and
056 * {@link #remove(int)}.
057 *
058 * <p>The documentation for each non-abstract method in this class describes its
059 * implementation in detail. Each of these methods may be overridden if the
060 * collection being implemented admits a more efficient implementation.
061 *
062 * <p>This class is a member of the
063 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
064 * Java Collections Framework</a>.
065 *
066 * @author Josh Bloch
067 * @author Neal Gafter
068 * @version 1.61, 06/24/07
069 * @since 1.2
070 */
071
072 public abstract class AbstractList<E> extends AbstractCollection<E>
073 implements List<E> {
074 /**
075 * Sole constructor. (For invocation by subclass constructors, typically
076 * implicit.)
077 */
078 protected AbstractList() {
079 }
080
081 /**
082 * Appends the specified element to the end of this list (optional
083 * operation).
084 *
085 * <p>Lists that support this operation may place limitations on what
086 * elements may be added to this list. In particular, some
087 * lists will refuse to add null elements, and others will impose
088 * restrictions on the type of elements that may be added. List
089 * classes should clearly specify in their documentation any restrictions
090 * on what elements may be added.
091 *
092 * <p>This implementation calls {@code add(size(), e)}.
093 *
094 * <p>Note that this implementation throws an
095 * {@code UnsupportedOperationException} unless
096 * {@link #add(int, Object) add(int, E)} is overridden.
097 *
098 * @param e element to be appended to this list
099 * @return {@code true} (as specified by {@link Collection#add})
100 * @throws UnsupportedOperationException if the {@code add} operation
101 * is not supported by this list
102 * @throws ClassCastException if the class of the specified element
103 * prevents it from being added to this list
104 * @throws NullPointerException if the specified element is null and this
105 * list does not permit null elements
106 * @throws IllegalArgumentException if some property of this element
107 * prevents it from being added to this list
108 */
109 public boolean add(E e) {
110 add(size(), e);
111 return true;
112 }
113
114 /**
115 * {@inheritDoc}
116 *
117 * @throws IndexOutOfBoundsException {@inheritDoc}
118 */
119 abstract public E get(int index);
120
121 /**
122 * {@inheritDoc}
123 *
124 * <p>This implementation always throws an
125 * {@code UnsupportedOperationException}.
126 *
127 * @throws UnsupportedOperationException {@inheritDoc}
128 * @throws ClassCastException {@inheritDoc}
129 * @throws NullPointerException {@inheritDoc}
130 * @throws IllegalArgumentException {@inheritDoc}
131 * @throws IndexOutOfBoundsException {@inheritDoc}
132 */
133 public E set(int index, E element) {
134 throw new UnsupportedOperationException();
135 }
136
137 /**
138 * {@inheritDoc}
139 *
140 * <p>This implementation always throws an
141 * {@code UnsupportedOperationException}.
142 *
143 * @throws UnsupportedOperationException {@inheritDoc}
144 * @throws ClassCastException {@inheritDoc}
145 * @throws NullPointerException {@inheritDoc}
146 * @throws IllegalArgumentException {@inheritDoc}
147 * @throws IndexOutOfBoundsException {@inheritDoc}
148 */
149 public void add(int index, E element) {
150 throw new UnsupportedOperationException();
151 }
152
153 /**
154 * {@inheritDoc}
155 *
156 * <p>This implementation always throws an
157 * {@code UnsupportedOperationException}.
158 *
159 * @throws UnsupportedOperationException {@inheritDoc}
160 * @throws IndexOutOfBoundsException {@inheritDoc}
161 */
162 public E remove(int index) {
163 throw new UnsupportedOperationException();
164 }
165
166 // Search Operations
167
168 /**
169 * {@inheritDoc}
170 *
171 * <p>This implementation first gets a list iterator (with
172 * {@code listIterator()}). Then, it iterates over the list until the
173 * specified element is found or the end of the list is reached.
174 *
175 * @throws ClassCastException {@inheritDoc}
176 * @throws NullPointerException {@inheritDoc}
177 */
178 public int indexOf(Object o) {
179 ListIterator<E> e = listIterator();
180 if (o == null) {
181 while (e.hasNext())
182 if (e.next() == null)
183 return e.previousIndex();
184 } else {
185 while (e.hasNext())
186 if (o.equals(e.next()))
187 return e.previousIndex();
188 }
189 return -1;
190 }
191
192 /**
193 * {@inheritDoc}
194 *
195 * <p>This implementation first gets a list iterator that points to the end
196 * of the list (with {@code listIterator(size())}). Then, it iterates
197 * backwards over the list until the specified element is found, or the
198 * beginning of the list is reached.
199 *
200 * @throws ClassCastException {@inheritDoc}
201 * @throws NullPointerException {@inheritDoc}
202 */
203 public int lastIndexOf(Object o) {
204 ListIterator<E> e = listIterator(size());
205 if (o == null) {
206 while (e.hasPrevious())
207 if (e.previous() == null)
208 return e.nextIndex();
209 } else {
210 while (e.hasPrevious())
211 if (o.equals(e.previous()))
212 return e.nextIndex();
213 }
214 return -1;
215 }
216
217 // Bulk Operations
218
219 /**
220 * Removes all of the elements from this list (optional operation).
221 * The list will be empty after this call returns.
222 *
223 * <p>This implementation calls {@code removeRange(0, size())}.
224 *
225 * <p>Note that this implementation throws an
226 * {@code UnsupportedOperationException} unless {@code remove(int
227 * index)} or {@code removeRange(int fromIndex, int toIndex)} is
228 * overridden.
229 *
230 * @throws UnsupportedOperationException if the {@code clear} operation
231 * is not supported by this list
232 */
233 public void clear() {
234 removeRange(0, size());
235 }
236
237 /**
238 * {@inheritDoc}
239 *
240 * <p>This implementation gets an iterator over the specified collection
241 * and iterates over it, inserting the elements obtained from the
242 * iterator into this list at the appropriate position, one at a time,
243 * using {@code add(int, E)}.
244 * Many implementations will override this method for efficiency.
245 *
246 * <p>Note that this implementation throws an
247 * {@code UnsupportedOperationException} unless
248 * {@link #add(int, Object) add(int, E)} is overridden.
249 *
250 * @throws UnsupportedOperationException {@inheritDoc}
251 * @throws ClassCastException {@inheritDoc}
252 * @throws NullPointerException {@inheritDoc}
253 * @throws IllegalArgumentException {@inheritDoc}
254 * @throws IndexOutOfBoundsException {@inheritDoc}
255 */
256 public boolean addAll(int index, Collection<? extends E> c) {
257 rangeCheckForAdd(index);
258 boolean modified = false;
259 Iterator<? extends E> e = c.iterator();
260 while (e.hasNext()) {
261 add(index++, e.next());
262 modified = true;
263 }
264 return modified;
265 }
266
267 // Iterators
268
269 /**
270 * Returns an iterator over the elements in this list in proper sequence.
271 *
272 * <p>This implementation returns a straightforward implementation of the
273 * iterator interface, relying on the backing list's {@code size()},
274 * {@code get(int)}, and {@code remove(int)} methods.
275 *
276 * <p>Note that the iterator returned by this method will throw an
277 * {@link UnsupportedOperationException} in response to its
278 * {@code remove} method unless the list's {@code remove(int)} method is
279 * overridden.
280 *
281 * <p>This implementation can be made to throw runtime exceptions in the
282 * face of concurrent modification, as described in the specification
283 * for the (protected) {@link #modCount} field.
284 *
285 * @return an iterator over the elements in this list in proper sequence
286 */
287 public Iterator<E> iterator() {
288 return new Itr();
289 }
290
291 /**
292 * {@inheritDoc}
293 *
294 * <p>This implementation returns {@code listIterator(0)}.
295 *
296 * @see #listIterator(int)
297 */
298 public ListIterator<E> listIterator() {
299 return listIterator(0);
300 }
301
302 /**
303 * {@inheritDoc}
304 *
305 * <p>This implementation returns a straightforward implementation of the
306 * {@code ListIterator} interface that extends the implementation of the
307 * {@code Iterator} interface returned by the {@code iterator()} method.
308 * The {@code ListIterator} implementation relies on the backing list's
309 * {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}
310 * and {@code remove(int)} methods.
311 *
312 * <p>Note that the list iterator returned by this implementation will
313 * throw an {@link UnsupportedOperationException} in response to its
314 * {@code remove}, {@code set} and {@code add} methods unless the
315 * list's {@code remove(int)}, {@code set(int, E)}, and
316 * {@code add(int, E)} methods are overridden.
317 *
318 * <p>This implementation can be made to throw runtime exceptions in the
319 * face of concurrent modification, as described in the specification for
320 * the (protected) {@link #modCount} field.
321 *
322 * @throws IndexOutOfBoundsException {@inheritDoc}
323 */
324 public ListIterator<E> listIterator(final int index) {
325 rangeCheckForAdd(index);
326
327 return new ListItr(index);
328 }
329
330 private class Itr implements Iterator<E> {
331 /**
332 * Index of element to be returned by subsequent call to next.
333 */
334 int cursor = 0;
335
336 /**
337 * Index of element returned by most recent call to next or
338 * previous. Reset to -1 if this element is deleted by a call
339 * to remove.
340 */
341 int lastRet = -1;
342
343 /**
344 * The modCount value that the iterator believes that the backing
345 * List should have. If this expectation is violated, the iterator
346 * has detected concurrent modification.
347 */
348 int expectedModCount = modCount;
349
350 public boolean hasNext() {
351 return cursor != size();
352 }
353
354 public E next() {
355 checkForComodification();
356 try {
357 int i = cursor;
358 E next = get(i);
359 lastRet = i;
360 cursor = i + 1;
361 return next;
362 } catch (IndexOutOfBoundsException e) {
363 checkForComodification();
364 throw new NoSuchElementException();
365 }
366 }
367
368 public void remove() {
369 if (lastRet < 0)
370 throw new IllegalStateException();
371 checkForComodification();
372
373 try {
374 AbstractList.this .remove(lastRet);
375 if (lastRet < cursor)
376 cursor--;
377 lastRet = -1;
378 expectedModCount = modCount;
379 } catch (IndexOutOfBoundsException e) {
380 throw new ConcurrentModificationException();
381 }
382 }
383
384 final void checkForComodification() {
385 if (modCount != expectedModCount)
386 throw new ConcurrentModificationException();
387 }
388 }
389
390 private class ListItr extends Itr implements ListIterator<E> {
391 ListItr(int index) {
392 cursor = index;
393 }
394
395 public boolean hasPrevious() {
396 return cursor != 0;
397 }
398
399 public E previous() {
400 checkForComodification();
401 try {
402 int i = cursor - 1;
403 E previous = get(i);
404 lastRet = cursor = i;
405 return previous;
406 } catch (IndexOutOfBoundsException e) {
407 checkForComodification();
408 throw new NoSuchElementException();
409 }
410 }
411
412 public int nextIndex() {
413 return cursor;
414 }
415
416 public int previousIndex() {
417 return cursor - 1;
418 }
419
420 public void set(E e) {
421 if (lastRet < 0)
422 throw new IllegalStateException();
423 checkForComodification();
424
425 try {
426 AbstractList.this .set(lastRet, e);
427 expectedModCount = modCount;
428 } catch (IndexOutOfBoundsException ex) {
429 throw new ConcurrentModificationException();
430 }
431 }
432
433 public void add(E e) {
434 checkForComodification();
435
436 try {
437 int i = cursor;
438 AbstractList.this .add(i, e);
439 lastRet = -1;
440 cursor = i + 1;
441 expectedModCount = modCount;
442 } catch (IndexOutOfBoundsException ex) {
443 throw new ConcurrentModificationException();
444 }
445 }
446 }
447
448 /**
449 * {@inheritDoc}
450 *
451 * <p>This implementation returns a list that subclasses
452 * {@code AbstractList}. The subclass stores, in private fields, the
453 * offset of the subList within the backing list, the size of the subList
454 * (which can change over its lifetime), and the expected
455 * {@code modCount} value of the backing list. There are two variants
456 * of the subclass, one of which implements {@code RandomAccess}.
457 * If this list implements {@code RandomAccess} the returned list will
458 * be an instance of the subclass that implements {@code RandomAccess}.
459 *
460 * <p>The subclass's {@code set(int, E)}, {@code get(int)},
461 * {@code add(int, E)}, {@code remove(int)}, {@code addAll(int,
462 * Collection)} and {@code removeRange(int, int)} methods all
463 * delegate to the corresponding methods on the backing abstract list,
464 * after bounds-checking the index and adjusting for the offset. The
465 * {@code addAll(Collection c)} method merely returns {@code addAll(size,
466 * c)}.
467 *
468 * <p>The {@code listIterator(int)} method returns a "wrapper object"
469 * over a list iterator on the backing list, which is created with the
470 * corresponding method on the backing list. The {@code iterator} method
471 * merely returns {@code listIterator()}, and the {@code size} method
472 * merely returns the subclass's {@code size} field.
473 *
474 * <p>All methods first check to see if the actual {@code modCount} of
475 * the backing list is equal to its expected value, and throw a
476 * {@code ConcurrentModificationException} if it is not.
477 *
478 * @throws IndexOutOfBoundsException if an endpoint index value is out of range
479 * {@code (fromIndex < 0 || toIndex > size)}
480 * @throws IllegalArgumentException if the endpoint indices are out of order
481 * {@code (fromIndex > toIndex)}
482 */
483 public List<E> subList(int fromIndex, int toIndex) {
484 return (this instanceof RandomAccess ? new RandomAccessSubList<E>(
485 this , fromIndex, toIndex)
486 : new SubList<E>(this , fromIndex, toIndex));
487 }
488
489 // Comparison and hashing
490
491 /**
492 * Compares the specified object with this list for equality. Returns
493 * {@code true} if and only if the specified object is also a list, both
494 * lists have the same size, and all corresponding pairs of elements in
495 * the two lists are <i>equal</i>. (Two elements {@code e1} and
496 * {@code e2} are <i>equal</i> if {@code (e1==null ? e2==null :
497 * e1.equals(e2))}.) In other words, two lists are defined to be
498 * equal if they contain the same elements in the same order.<p>
499 *
500 * This implementation first checks if the specified object is this
501 * list. If so, it returns {@code true}; if not, it checks if the
502 * specified object is a list. If not, it returns {@code false}; if so,
503 * it iterates over both lists, comparing corresponding pairs of elements.
504 * If any comparison returns {@code false}, this method returns
505 * {@code false}. If either iterator runs out of elements before the
506 * other it returns {@code false} (as the lists are of unequal length);
507 * otherwise it returns {@code true} when the iterations complete.
508 *
509 * @param o the object to be compared for equality with this list
510 * @return {@code true} if the specified object is equal to this list
511 */
512 public boolean equals(Object o) {
513 if (o == this )
514 return true;
515 if (!(o instanceof List))
516 return false;
517
518 ListIterator<E> e1 = listIterator();
519 ListIterator e2 = ((List) o).listIterator();
520 while (e1.hasNext() && e2.hasNext()) {
521 E o1 = e1.next();
522 Object o2 = e2.next();
523 if (!(o1 == null ? o2 == null : o1.equals(o2)))
524 return false;
525 }
526 return !(e1.hasNext() || e2.hasNext());
527 }
528
529 /**
530 * Returns the hash code value for this list.
531 *
532 * <p>This implementation uses exactly the code that is used to define the
533 * list hash function in the documentation for the {@link List#hashCode}
534 * method.
535 *
536 * @return the hash code value for this list
537 */
538 public int hashCode() {
539 int hashCode = 1;
540 for (E e : this )
541 hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
542 return hashCode;
543 }
544
545 /**
546 * Removes from this list all of the elements whose index is between
547 * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
548 * Shifts any succeeding elements to the left (reduces their index).
549 * This call shortens the list by {@code (toIndex - fromIndex)} elements.
550 * (If {@code toIndex==fromIndex}, this operation has no effect.)
551 *
552 * <p>This method is called by the {@code clear} operation on this list
553 * and its subLists. Overriding this method to take advantage of
554 * the internals of the list implementation can <i>substantially</i>
555 * improve the performance of the {@code clear} operation on this list
556 * and its subLists.
557 *
558 * <p>This implementation gets a list iterator positioned before
559 * {@code fromIndex}, and repeatedly calls {@code ListIterator.next}
560 * followed by {@code ListIterator.remove} until the entire range has
561 * been removed. <b>Note: if {@code ListIterator.remove} requires linear
562 * time, this implementation requires quadratic time.</b>
563 *
564 * @param fromIndex index of first element to be removed
565 * @param toIndex index after last element to be removed
566 */
567 protected void removeRange(int fromIndex, int toIndex) {
568 ListIterator<E> it = listIterator(fromIndex);
569 for (int i = 0, n = toIndex - fromIndex; i < n; i++) {
570 it.next();
571 it.remove();
572 }
573 }
574
575 /**
576 * The number of times this list has been <i>structurally modified</i>.
577 * Structural modifications are those that change the size of the
578 * list, or otherwise perturb it in such a fashion that iterations in
579 * progress may yield incorrect results.
580 *
581 * <p>This field is used by the iterator and list iterator implementation
582 * returned by the {@code iterator} and {@code listIterator} methods.
583 * If the value of this field changes unexpectedly, the iterator (or list
584 * iterator) will throw a {@code ConcurrentModificationException} in
585 * response to the {@code next}, {@code remove}, {@code previous},
586 * {@code set} or {@code add} operations. This provides
587 * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
588 * the face of concurrent modification during iteration.
589 *
590 * <p><b>Use of this field by subclasses is optional.</b> If a subclass
591 * wishes to provide fail-fast iterators (and list iterators), then it
592 * merely has to increment this field in its {@code add(int, E)} and
593 * {@code remove(int)} methods (and any other methods that it overrides
594 * that result in structural modifications to the list). A single call to
595 * {@code add(int, E)} or {@code remove(int)} must add no more than
596 * one to this field, or the iterators (and list iterators) will throw
597 * bogus {@code ConcurrentModificationExceptions}. If an implementation
598 * does not wish to provide fail-fast iterators, this field may be
599 * ignored.
600 */
601 protected transient int modCount = 0;
602
603 private void rangeCheckForAdd(int index) {
604 if (index < 0 || index > size())
605 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
606 }
607
608 private String outOfBoundsMsg(int index) {
609 return "Index: " + index + ", Size: " + size();
610 }
611 }
612
613 class SubList<E> extends AbstractList<E> {
614 private final AbstractList<E> l;
615 private final int offset;
616 private int size;
617
618 SubList(AbstractList<E> list, int fromIndex, int toIndex) {
619 if (fromIndex < 0)
620 throw new IndexOutOfBoundsException("fromIndex = "
621 + fromIndex);
622 if (toIndex > list.size())
623 throw new IndexOutOfBoundsException("toIndex = " + toIndex);
624 if (fromIndex > toIndex)
625 throw new IllegalArgumentException("fromIndex(" + fromIndex
626 + ") > toIndex(" + toIndex + ")");
627 l = list;
628 offset = fromIndex;
629 size = toIndex - fromIndex;
630 this .modCount = l.modCount;
631 }
632
633 public E set(int index, E element) {
634 rangeCheck(index);
635 checkForComodification();
636 return l.set(index + offset, element);
637 }
638
639 public E get(int index) {
640 rangeCheck(index);
641 checkForComodification();
642 return l.get(index + offset);
643 }
644
645 public int size() {
646 checkForComodification();
647 return size;
648 }
649
650 public void add(int index, E element) {
651 rangeCheckForAdd(index);
652 checkForComodification();
653 l.add(index + offset, element);
654 this .modCount = l.modCount;
655 size++;
656 }
657
658 public E remove(int index) {
659 rangeCheck(index);
660 checkForComodification();
661 E result = l.remove(index + offset);
662 this .modCount = l.modCount;
663 size--;
664 return result;
665 }
666
667 protected void removeRange(int fromIndex, int toIndex) {
668 checkForComodification();
669 l.removeRange(fromIndex + offset, toIndex + offset);
670 this .modCount = l.modCount;
671 size -= (toIndex - fromIndex);
672 }
673
674 public boolean addAll(Collection<? extends E> c) {
675 return addAll(size, c);
676 }
677
678 public boolean addAll(int index, Collection<? extends E> c) {
679 rangeCheckForAdd(index);
680 int cSize = c.size();
681 if (cSize == 0)
682 return false;
683
684 checkForComodification();
685 l.addAll(offset + index, c);
686 this .modCount = l.modCount;
687 size += cSize;
688 return true;
689 }
690
691 public Iterator<E> iterator() {
692 return listIterator();
693 }
694
695 public ListIterator<E> listIterator(final int index) {
696 checkForComodification();
697 rangeCheckForAdd(index);
698
699 return new ListIterator<E>() {
700 private final ListIterator<E> i = l.listIterator(index
701 + offset);
702
703 public boolean hasNext() {
704 return nextIndex() < size;
705 }
706
707 public E next() {
708 if (hasNext())
709 return i.next();
710 else
711 throw new NoSuchElementException();
712 }
713
714 public boolean hasPrevious() {
715 return previousIndex() >= 0;
716 }
717
718 public E previous() {
719 if (hasPrevious())
720 return i.previous();
721 else
722 throw new NoSuchElementException();
723 }
724
725 public int nextIndex() {
726 return i.nextIndex() - offset;
727 }
728
729 public int previousIndex() {
730 return i.previousIndex() - offset;
731 }
732
733 public void remove() {
734 i.remove();
735 SubList.this .modCount = l.modCount;
736 size--;
737 }
738
739 public void set(E e) {
740 i.set(e);
741 }
742
743 public void add(E e) {
744 i.add(e);
745 SubList.this .modCount = l.modCount;
746 size++;
747 }
748 };
749 }
750
751 public List<E> subList(int fromIndex, int toIndex) {
752 return new SubList<E>(this , fromIndex, toIndex);
753 }
754
755 private void rangeCheck(int index) {
756 if (index < 0 || index >= size)
757 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
758 }
759
760 private void rangeCheckForAdd(int index) {
761 if (index < 0 || index > size)
762 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
763 }
764
765 private String outOfBoundsMsg(int index) {
766 return "Index: " + index + ", Size: " + size;
767 }
768
769 private void checkForComodification() {
770 if (this .modCount != l.modCount)
771 throw new ConcurrentModificationException();
772 }
773 }
774
775 class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
776 RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
777 super (list, fromIndex, toIndex);
778 }
779
780 public List<E> subList(int fromIndex, int toIndex) {
781 return new RandomAccessSubList<E>(this, fromIndex, toIndex);
782 }
783 }
|