1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/rt/emul/compact/src/main/java/java/util/AbstractList.java Tue Feb 26 16:54:16 2013 +0100
1.3 @@ -0,0 +1,781 @@
1.4 +/*
1.5 + * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
1.7 + *
1.8 + * This code is free software; you can redistribute it and/or modify it
1.9 + * under the terms of the GNU General Public License version 2 only, as
1.10 + * published by the Free Software Foundation. Oracle designates this
1.11 + * particular file as subject to the "Classpath" exception as provided
1.12 + * by Oracle in the LICENSE file that accompanied this code.
1.13 + *
1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1.17 + * version 2 for more details (a copy is included in the LICENSE file that
1.18 + * accompanied this code).
1.19 + *
1.20 + * You should have received a copy of the GNU General Public License version
1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1.23 + *
1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
1.25 + * or visit www.oracle.com if you need additional information or have any
1.26 + * questions.
1.27 + */
1.28 +
1.29 +package java.util;
1.30 +
1.31 +/**
1.32 + * This class provides a skeletal implementation of the {@link List}
1.33 + * interface to minimize the effort required to implement this interface
1.34 + * backed by a "random access" data store (such as an array). For sequential
1.35 + * access data (such as a linked list), {@link AbstractSequentialList} should
1.36 + * be used in preference to this class.
1.37 + *
1.38 + * <p>To implement an unmodifiable list, the programmer needs only to extend
1.39 + * this class and provide implementations for the {@link #get(int)} and
1.40 + * {@link List#size() size()} methods.
1.41 + *
1.42 + * <p>To implement a modifiable list, the programmer must additionally
1.43 + * override the {@link #set(int, Object) set(int, E)} method (which otherwise
1.44 + * throws an {@code UnsupportedOperationException}). If the list is
1.45 + * variable-size the programmer must additionally override the
1.46 + * {@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods.
1.47 + *
1.48 + * <p>The programmer should generally provide a void (no argument) and collection
1.49 + * constructor, as per the recommendation in the {@link Collection} interface
1.50 + * specification.
1.51 + *
1.52 + * <p>Unlike the other abstract collection implementations, the programmer does
1.53 + * <i>not</i> have to provide an iterator implementation; the iterator and
1.54 + * list iterator are implemented by this class, on top of the "random access"
1.55 + * methods:
1.56 + * {@link #get(int)},
1.57 + * {@link #set(int, Object) set(int, E)},
1.58 + * {@link #add(int, Object) add(int, E)} and
1.59 + * {@link #remove(int)}.
1.60 + *
1.61 + * <p>The documentation for each non-abstract method in this class describes its
1.62 + * implementation in detail. Each of these methods may be overridden if the
1.63 + * collection being implemented admits a more efficient implementation.
1.64 + *
1.65 + * <p>This class is a member of the
1.66 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
1.67 + * Java Collections Framework</a>.
1.68 + *
1.69 + * @author Josh Bloch
1.70 + * @author Neal Gafter
1.71 + * @since 1.2
1.72 + */
1.73 +
1.74 +public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
1.75 + /**
1.76 + * Sole constructor. (For invocation by subclass constructors, typically
1.77 + * implicit.)
1.78 + */
1.79 + protected AbstractList() {
1.80 + }
1.81 +
1.82 + /**
1.83 + * Appends the specified element to the end of this list (optional
1.84 + * operation).
1.85 + *
1.86 + * <p>Lists that support this operation may place limitations on what
1.87 + * elements may be added to this list. In particular, some
1.88 + * lists will refuse to add null elements, and others will impose
1.89 + * restrictions on the type of elements that may be added. List
1.90 + * classes should clearly specify in their documentation any restrictions
1.91 + * on what elements may be added.
1.92 + *
1.93 + * <p>This implementation calls {@code add(size(), e)}.
1.94 + *
1.95 + * <p>Note that this implementation throws an
1.96 + * {@code UnsupportedOperationException} unless
1.97 + * {@link #add(int, Object) add(int, E)} is overridden.
1.98 + *
1.99 + * @param e element to be appended to this list
1.100 + * @return {@code true} (as specified by {@link Collection#add})
1.101 + * @throws UnsupportedOperationException if the {@code add} operation
1.102 + * is not supported by this list
1.103 + * @throws ClassCastException if the class of the specified element
1.104 + * prevents it from being added to this list
1.105 + * @throws NullPointerException if the specified element is null and this
1.106 + * list does not permit null elements
1.107 + * @throws IllegalArgumentException if some property of this element
1.108 + * prevents it from being added to this list
1.109 + */
1.110 + public boolean add(E e) {
1.111 + add(size(), e);
1.112 + return true;
1.113 + }
1.114 +
1.115 + /**
1.116 + * {@inheritDoc}
1.117 + *
1.118 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.119 + */
1.120 + abstract public E get(int index);
1.121 +
1.122 + /**
1.123 + * {@inheritDoc}
1.124 + *
1.125 + * <p>This implementation always throws an
1.126 + * {@code UnsupportedOperationException}.
1.127 + *
1.128 + * @throws UnsupportedOperationException {@inheritDoc}
1.129 + * @throws ClassCastException {@inheritDoc}
1.130 + * @throws NullPointerException {@inheritDoc}
1.131 + * @throws IllegalArgumentException {@inheritDoc}
1.132 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.133 + */
1.134 + public E set(int index, E element) {
1.135 + throw new UnsupportedOperationException();
1.136 + }
1.137 +
1.138 + /**
1.139 + * {@inheritDoc}
1.140 + *
1.141 + * <p>This implementation always throws an
1.142 + * {@code UnsupportedOperationException}.
1.143 + *
1.144 + * @throws UnsupportedOperationException {@inheritDoc}
1.145 + * @throws ClassCastException {@inheritDoc}
1.146 + * @throws NullPointerException {@inheritDoc}
1.147 + * @throws IllegalArgumentException {@inheritDoc}
1.148 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.149 + */
1.150 + public void add(int index, E element) {
1.151 + throw new UnsupportedOperationException();
1.152 + }
1.153 +
1.154 + /**
1.155 + * {@inheritDoc}
1.156 + *
1.157 + * <p>This implementation always throws an
1.158 + * {@code UnsupportedOperationException}.
1.159 + *
1.160 + * @throws UnsupportedOperationException {@inheritDoc}
1.161 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.162 + */
1.163 + public E remove(int index) {
1.164 + throw new UnsupportedOperationException();
1.165 + }
1.166 +
1.167 +
1.168 + // Search Operations
1.169 +
1.170 + /**
1.171 + * {@inheritDoc}
1.172 + *
1.173 + * <p>This implementation first gets a list iterator (with
1.174 + * {@code listIterator()}). Then, it iterates over the list until the
1.175 + * specified element is found or the end of the list is reached.
1.176 + *
1.177 + * @throws ClassCastException {@inheritDoc}
1.178 + * @throws NullPointerException {@inheritDoc}
1.179 + */
1.180 + public int indexOf(Object o) {
1.181 + ListIterator<E> it = listIterator();
1.182 + if (o==null) {
1.183 + while (it.hasNext())
1.184 + if (it.next()==null)
1.185 + return it.previousIndex();
1.186 + } else {
1.187 + while (it.hasNext())
1.188 + if (o.equals(it.next()))
1.189 + return it.previousIndex();
1.190 + }
1.191 + return -1;
1.192 + }
1.193 +
1.194 + /**
1.195 + * {@inheritDoc}
1.196 + *
1.197 + * <p>This implementation first gets a list iterator that points to the end
1.198 + * of the list (with {@code listIterator(size())}). Then, it iterates
1.199 + * backwards over the list until the specified element is found, or the
1.200 + * beginning of the list is reached.
1.201 + *
1.202 + * @throws ClassCastException {@inheritDoc}
1.203 + * @throws NullPointerException {@inheritDoc}
1.204 + */
1.205 + public int lastIndexOf(Object o) {
1.206 + ListIterator<E> it = listIterator(size());
1.207 + if (o==null) {
1.208 + while (it.hasPrevious())
1.209 + if (it.previous()==null)
1.210 + return it.nextIndex();
1.211 + } else {
1.212 + while (it.hasPrevious())
1.213 + if (o.equals(it.previous()))
1.214 + return it.nextIndex();
1.215 + }
1.216 + return -1;
1.217 + }
1.218 +
1.219 +
1.220 + // Bulk Operations
1.221 +
1.222 + /**
1.223 + * Removes all of the elements from this list (optional operation).
1.224 + * The list will be empty after this call returns.
1.225 + *
1.226 + * <p>This implementation calls {@code removeRange(0, size())}.
1.227 + *
1.228 + * <p>Note that this implementation throws an
1.229 + * {@code UnsupportedOperationException} unless {@code remove(int
1.230 + * index)} or {@code removeRange(int fromIndex, int toIndex)} is
1.231 + * overridden.
1.232 + *
1.233 + * @throws UnsupportedOperationException if the {@code clear} operation
1.234 + * is not supported by this list
1.235 + */
1.236 + public void clear() {
1.237 + removeRange(0, size());
1.238 + }
1.239 +
1.240 + /**
1.241 + * {@inheritDoc}
1.242 + *
1.243 + * <p>This implementation gets an iterator over the specified collection
1.244 + * and iterates over it, inserting the elements obtained from the
1.245 + * iterator into this list at the appropriate position, one at a time,
1.246 + * using {@code add(int, E)}.
1.247 + * Many implementations will override this method for efficiency.
1.248 + *
1.249 + * <p>Note that this implementation throws an
1.250 + * {@code UnsupportedOperationException} unless
1.251 + * {@link #add(int, Object) add(int, E)} is overridden.
1.252 + *
1.253 + * @throws UnsupportedOperationException {@inheritDoc}
1.254 + * @throws ClassCastException {@inheritDoc}
1.255 + * @throws NullPointerException {@inheritDoc}
1.256 + * @throws IllegalArgumentException {@inheritDoc}
1.257 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.258 + */
1.259 + public boolean addAll(int index, Collection<? extends E> c) {
1.260 + rangeCheckForAdd(index);
1.261 + boolean modified = false;
1.262 + for (E e : c) {
1.263 + add(index++, e);
1.264 + modified = true;
1.265 + }
1.266 + return modified;
1.267 + }
1.268 +
1.269 +
1.270 + // Iterators
1.271 +
1.272 + /**
1.273 + * Returns an iterator over the elements in this list in proper sequence.
1.274 + *
1.275 + * <p>This implementation returns a straightforward implementation of the
1.276 + * iterator interface, relying on the backing list's {@code size()},
1.277 + * {@code get(int)}, and {@code remove(int)} methods.
1.278 + *
1.279 + * <p>Note that the iterator returned by this method will throw an
1.280 + * {@link UnsupportedOperationException} in response to its
1.281 + * {@code remove} method unless the list's {@code remove(int)} method is
1.282 + * overridden.
1.283 + *
1.284 + * <p>This implementation can be made to throw runtime exceptions in the
1.285 + * face of concurrent modification, as described in the specification
1.286 + * for the (protected) {@link #modCount} field.
1.287 + *
1.288 + * @return an iterator over the elements in this list in proper sequence
1.289 + */
1.290 + public Iterator<E> iterator() {
1.291 + return new Itr();
1.292 + }
1.293 +
1.294 + /**
1.295 + * {@inheritDoc}
1.296 + *
1.297 + * <p>This implementation returns {@code listIterator(0)}.
1.298 + *
1.299 + * @see #listIterator(int)
1.300 + */
1.301 + public ListIterator<E> listIterator() {
1.302 + return listIterator(0);
1.303 + }
1.304 +
1.305 + /**
1.306 + * {@inheritDoc}
1.307 + *
1.308 + * <p>This implementation returns a straightforward implementation of the
1.309 + * {@code ListIterator} interface that extends the implementation of the
1.310 + * {@code Iterator} interface returned by the {@code iterator()} method.
1.311 + * The {@code ListIterator} implementation relies on the backing list's
1.312 + * {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}
1.313 + * and {@code remove(int)} methods.
1.314 + *
1.315 + * <p>Note that the list iterator returned by this implementation will
1.316 + * throw an {@link UnsupportedOperationException} in response to its
1.317 + * {@code remove}, {@code set} and {@code add} methods unless the
1.318 + * list's {@code remove(int)}, {@code set(int, E)}, and
1.319 + * {@code add(int, E)} methods are overridden.
1.320 + *
1.321 + * <p>This implementation can be made to throw runtime exceptions in the
1.322 + * face of concurrent modification, as described in the specification for
1.323 + * the (protected) {@link #modCount} field.
1.324 + *
1.325 + * @throws IndexOutOfBoundsException {@inheritDoc}
1.326 + */
1.327 + public ListIterator<E> listIterator(final int index) {
1.328 + rangeCheckForAdd(index);
1.329 +
1.330 + return new ListItr(index);
1.331 + }
1.332 +
1.333 + private class Itr implements Iterator<E> {
1.334 + /**
1.335 + * Index of element to be returned by subsequent call to next.
1.336 + */
1.337 + int cursor = 0;
1.338 +
1.339 + /**
1.340 + * Index of element returned by most recent call to next or
1.341 + * previous. Reset to -1 if this element is deleted by a call
1.342 + * to remove.
1.343 + */
1.344 + int lastRet = -1;
1.345 +
1.346 + /**
1.347 + * The modCount value that the iterator believes that the backing
1.348 + * List should have. If this expectation is violated, the iterator
1.349 + * has detected concurrent modification.
1.350 + */
1.351 + int expectedModCount = modCount;
1.352 +
1.353 + public boolean hasNext() {
1.354 + return cursor != size();
1.355 + }
1.356 +
1.357 + public E next() {
1.358 + checkForComodification();
1.359 + try {
1.360 + int i = cursor;
1.361 + E next = get(i);
1.362 + lastRet = i;
1.363 + cursor = i + 1;
1.364 + return next;
1.365 + } catch (IndexOutOfBoundsException e) {
1.366 + checkForComodification();
1.367 + throw new NoSuchElementException();
1.368 + }
1.369 + }
1.370 +
1.371 + public void remove() {
1.372 + if (lastRet < 0)
1.373 + throw new IllegalStateException();
1.374 + checkForComodification();
1.375 +
1.376 + try {
1.377 + AbstractList.this.remove(lastRet);
1.378 + if (lastRet < cursor)
1.379 + cursor--;
1.380 + lastRet = -1;
1.381 + expectedModCount = modCount;
1.382 + } catch (IndexOutOfBoundsException e) {
1.383 + throw new ConcurrentModificationException();
1.384 + }
1.385 + }
1.386 +
1.387 + final void checkForComodification() {
1.388 + if (modCount != expectedModCount)
1.389 + throw new ConcurrentModificationException();
1.390 + }
1.391 + }
1.392 +
1.393 + private class ListItr extends Itr implements ListIterator<E> {
1.394 + ListItr(int index) {
1.395 + cursor = index;
1.396 + }
1.397 +
1.398 + public boolean hasPrevious() {
1.399 + return cursor != 0;
1.400 + }
1.401 +
1.402 + public E previous() {
1.403 + checkForComodification();
1.404 + try {
1.405 + int i = cursor - 1;
1.406 + E previous = get(i);
1.407 + lastRet = cursor = i;
1.408 + return previous;
1.409 + } catch (IndexOutOfBoundsException e) {
1.410 + checkForComodification();
1.411 + throw new NoSuchElementException();
1.412 + }
1.413 + }
1.414 +
1.415 + public int nextIndex() {
1.416 + return cursor;
1.417 + }
1.418 +
1.419 + public int previousIndex() {
1.420 + return cursor-1;
1.421 + }
1.422 +
1.423 + public void set(E e) {
1.424 + if (lastRet < 0)
1.425 + throw new IllegalStateException();
1.426 + checkForComodification();
1.427 +
1.428 + try {
1.429 + AbstractList.this.set(lastRet, e);
1.430 + expectedModCount = modCount;
1.431 + } catch (IndexOutOfBoundsException ex) {
1.432 + throw new ConcurrentModificationException();
1.433 + }
1.434 + }
1.435 +
1.436 + public void add(E e) {
1.437 + checkForComodification();
1.438 +
1.439 + try {
1.440 + int i = cursor;
1.441 + AbstractList.this.add(i, e);
1.442 + lastRet = -1;
1.443 + cursor = i + 1;
1.444 + expectedModCount = modCount;
1.445 + } catch (IndexOutOfBoundsException ex) {
1.446 + throw new ConcurrentModificationException();
1.447 + }
1.448 + }
1.449 + }
1.450 +
1.451 + /**
1.452 + * {@inheritDoc}
1.453 + *
1.454 + * <p>This implementation returns a list that subclasses
1.455 + * {@code AbstractList}. The subclass stores, in private fields, the
1.456 + * offset of the subList within the backing list, the size of the subList
1.457 + * (which can change over its lifetime), and the expected
1.458 + * {@code modCount} value of the backing list. There are two variants
1.459 + * of the subclass, one of which implements {@code RandomAccess}.
1.460 + * If this list implements {@code RandomAccess} the returned list will
1.461 + * be an instance of the subclass that implements {@code RandomAccess}.
1.462 + *
1.463 + * <p>The subclass's {@code set(int, E)}, {@code get(int)},
1.464 + * {@code add(int, E)}, {@code remove(int)}, {@code addAll(int,
1.465 + * Collection)} and {@code removeRange(int, int)} methods all
1.466 + * delegate to the corresponding methods on the backing abstract list,
1.467 + * after bounds-checking the index and adjusting for the offset. The
1.468 + * {@code addAll(Collection c)} method merely returns {@code addAll(size,
1.469 + * c)}.
1.470 + *
1.471 + * <p>The {@code listIterator(int)} method returns a "wrapper object"
1.472 + * over a list iterator on the backing list, which is created with the
1.473 + * corresponding method on the backing list. The {@code iterator} method
1.474 + * merely returns {@code listIterator()}, and the {@code size} method
1.475 + * merely returns the subclass's {@code size} field.
1.476 + *
1.477 + * <p>All methods first check to see if the actual {@code modCount} of
1.478 + * the backing list is equal to its expected value, and throw a
1.479 + * {@code ConcurrentModificationException} if it is not.
1.480 + *
1.481 + * @throws IndexOutOfBoundsException if an endpoint index value is out of range
1.482 + * {@code (fromIndex < 0 || toIndex > size)}
1.483 + * @throws IllegalArgumentException if the endpoint indices are out of order
1.484 + * {@code (fromIndex > toIndex)}
1.485 + */
1.486 + public List<E> subList(int fromIndex, int toIndex) {
1.487 + return (this instanceof RandomAccess ?
1.488 + new RandomAccessSubList<>(this, fromIndex, toIndex) :
1.489 + new SubList<>(this, fromIndex, toIndex));
1.490 + }
1.491 +
1.492 + // Comparison and hashing
1.493 +
1.494 + /**
1.495 + * Compares the specified object with this list for equality. Returns
1.496 + * {@code true} if and only if the specified object is also a list, both
1.497 + * lists have the same size, and all corresponding pairs of elements in
1.498 + * the two lists are <i>equal</i>. (Two elements {@code e1} and
1.499 + * {@code e2} are <i>equal</i> if {@code (e1==null ? e2==null :
1.500 + * e1.equals(e2))}.) In other words, two lists are defined to be
1.501 + * equal if they contain the same elements in the same order.<p>
1.502 + *
1.503 + * This implementation first checks if the specified object is this
1.504 + * list. If so, it returns {@code true}; if not, it checks if the
1.505 + * specified object is a list. If not, it returns {@code false}; if so,
1.506 + * it iterates over both lists, comparing corresponding pairs of elements.
1.507 + * If any comparison returns {@code false}, this method returns
1.508 + * {@code false}. If either iterator runs out of elements before the
1.509 + * other it returns {@code false} (as the lists are of unequal length);
1.510 + * otherwise it returns {@code true} when the iterations complete.
1.511 + *
1.512 + * @param o the object to be compared for equality with this list
1.513 + * @return {@code true} if the specified object is equal to this list
1.514 + */
1.515 + public boolean equals(Object o) {
1.516 + if (o == this)
1.517 + return true;
1.518 + if (!(o instanceof List))
1.519 + return false;
1.520 +
1.521 + ListIterator<E> e1 = listIterator();
1.522 + ListIterator e2 = ((List) o).listIterator();
1.523 + while (e1.hasNext() && e2.hasNext()) {
1.524 + E o1 = e1.next();
1.525 + Object o2 = e2.next();
1.526 + if (!(o1==null ? o2==null : o1.equals(o2)))
1.527 + return false;
1.528 + }
1.529 + return !(e1.hasNext() || e2.hasNext());
1.530 + }
1.531 +
1.532 + /**
1.533 + * Returns the hash code value for this list.
1.534 + *
1.535 + * <p>This implementation uses exactly the code that is used to define the
1.536 + * list hash function in the documentation for the {@link List#hashCode}
1.537 + * method.
1.538 + *
1.539 + * @return the hash code value for this list
1.540 + */
1.541 + public int hashCode() {
1.542 + int hashCode = 1;
1.543 + for (E e : this)
1.544 + hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
1.545 + return hashCode;
1.546 + }
1.547 +
1.548 + /**
1.549 + * Removes from this list all of the elements whose index is between
1.550 + * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
1.551 + * Shifts any succeeding elements to the left (reduces their index).
1.552 + * This call shortens the list by {@code (toIndex - fromIndex)} elements.
1.553 + * (If {@code toIndex==fromIndex}, this operation has no effect.)
1.554 + *
1.555 + * <p>This method is called by the {@code clear} operation on this list
1.556 + * and its subLists. Overriding this method to take advantage of
1.557 + * the internals of the list implementation can <i>substantially</i>
1.558 + * improve the performance of the {@code clear} operation on this list
1.559 + * and its subLists.
1.560 + *
1.561 + * <p>This implementation gets a list iterator positioned before
1.562 + * {@code fromIndex}, and repeatedly calls {@code ListIterator.next}
1.563 + * followed by {@code ListIterator.remove} until the entire range has
1.564 + * been removed. <b>Note: if {@code ListIterator.remove} requires linear
1.565 + * time, this implementation requires quadratic time.</b>
1.566 + *
1.567 + * @param fromIndex index of first element to be removed
1.568 + * @param toIndex index after last element to be removed
1.569 + */
1.570 + protected void removeRange(int fromIndex, int toIndex) {
1.571 + ListIterator<E> it = listIterator(fromIndex);
1.572 + for (int i=0, n=toIndex-fromIndex; i<n; i++) {
1.573 + it.next();
1.574 + it.remove();
1.575 + }
1.576 + }
1.577 +
1.578 + /**
1.579 + * The number of times this list has been <i>structurally modified</i>.
1.580 + * Structural modifications are those that change the size of the
1.581 + * list, or otherwise perturb it in such a fashion that iterations in
1.582 + * progress may yield incorrect results.
1.583 + *
1.584 + * <p>This field is used by the iterator and list iterator implementation
1.585 + * returned by the {@code iterator} and {@code listIterator} methods.
1.586 + * If the value of this field changes unexpectedly, the iterator (or list
1.587 + * iterator) will throw a {@code ConcurrentModificationException} in
1.588 + * response to the {@code next}, {@code remove}, {@code previous},
1.589 + * {@code set} or {@code add} operations. This provides
1.590 + * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
1.591 + * the face of concurrent modification during iteration.
1.592 + *
1.593 + * <p><b>Use of this field by subclasses is optional.</b> If a subclass
1.594 + * wishes to provide fail-fast iterators (and list iterators), then it
1.595 + * merely has to increment this field in its {@code add(int, E)} and
1.596 + * {@code remove(int)} methods (and any other methods that it overrides
1.597 + * that result in structural modifications to the list). A single call to
1.598 + * {@code add(int, E)} or {@code remove(int)} must add no more than
1.599 + * one to this field, or the iterators (and list iterators) will throw
1.600 + * bogus {@code ConcurrentModificationExceptions}. If an implementation
1.601 + * does not wish to provide fail-fast iterators, this field may be
1.602 + * ignored.
1.603 + */
1.604 + protected transient int modCount = 0;
1.605 +
1.606 + private void rangeCheckForAdd(int index) {
1.607 + if (index < 0 || index > size())
1.608 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1.609 + }
1.610 +
1.611 + private String outOfBoundsMsg(int index) {
1.612 + return "Index: "+index+", Size: "+size();
1.613 + }
1.614 +}
1.615 +
1.616 +class SubList<E> extends AbstractList<E> {
1.617 + private final AbstractList<E> l;
1.618 + private final int offset;
1.619 + private int size;
1.620 +
1.621 + SubList(AbstractList<E> list, int fromIndex, int toIndex) {
1.622 + if (fromIndex < 0)
1.623 + throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
1.624 + if (toIndex > list.size())
1.625 + throw new IndexOutOfBoundsException("toIndex = " + toIndex);
1.626 + if (fromIndex > toIndex)
1.627 + throw new IllegalArgumentException("fromIndex(" + fromIndex +
1.628 + ") > toIndex(" + toIndex + ")");
1.629 + l = list;
1.630 + offset = fromIndex;
1.631 + size = toIndex - fromIndex;
1.632 + this.modCount = l.modCount;
1.633 + }
1.634 +
1.635 + public E set(int index, E element) {
1.636 + rangeCheck(index);
1.637 + checkForComodification();
1.638 + return l.set(index+offset, element);
1.639 + }
1.640 +
1.641 + public E get(int index) {
1.642 + rangeCheck(index);
1.643 + checkForComodification();
1.644 + return l.get(index+offset);
1.645 + }
1.646 +
1.647 + public int size() {
1.648 + checkForComodification();
1.649 + return size;
1.650 + }
1.651 +
1.652 + public void add(int index, E element) {
1.653 + rangeCheckForAdd(index);
1.654 + checkForComodification();
1.655 + l.add(index+offset, element);
1.656 + this.modCount = l.modCount;
1.657 + size++;
1.658 + }
1.659 +
1.660 + public E remove(int index) {
1.661 + rangeCheck(index);
1.662 + checkForComodification();
1.663 + E result = l.remove(index+offset);
1.664 + this.modCount = l.modCount;
1.665 + size--;
1.666 + return result;
1.667 + }
1.668 +
1.669 + protected void removeRange(int fromIndex, int toIndex) {
1.670 + checkForComodification();
1.671 + l.removeRange(fromIndex+offset, toIndex+offset);
1.672 + this.modCount = l.modCount;
1.673 + size -= (toIndex-fromIndex);
1.674 + }
1.675 +
1.676 + public boolean addAll(Collection<? extends E> c) {
1.677 + return addAll(size, c);
1.678 + }
1.679 +
1.680 + public boolean addAll(int index, Collection<? extends E> c) {
1.681 + rangeCheckForAdd(index);
1.682 + int cSize = c.size();
1.683 + if (cSize==0)
1.684 + return false;
1.685 +
1.686 + checkForComodification();
1.687 + l.addAll(offset+index, c);
1.688 + this.modCount = l.modCount;
1.689 + size += cSize;
1.690 + return true;
1.691 + }
1.692 +
1.693 + public Iterator<E> iterator() {
1.694 + return listIterator();
1.695 + }
1.696 +
1.697 + public ListIterator<E> listIterator(final int index) {
1.698 + checkForComodification();
1.699 + rangeCheckForAdd(index);
1.700 +
1.701 + return new ListIterator<E>() {
1.702 + private final ListIterator<E> i = l.listIterator(index+offset);
1.703 +
1.704 + public boolean hasNext() {
1.705 + return nextIndex() < size;
1.706 + }
1.707 +
1.708 + public E next() {
1.709 + if (hasNext())
1.710 + return i.next();
1.711 + else
1.712 + throw new NoSuchElementException();
1.713 + }
1.714 +
1.715 + public boolean hasPrevious() {
1.716 + return previousIndex() >= 0;
1.717 + }
1.718 +
1.719 + public E previous() {
1.720 + if (hasPrevious())
1.721 + return i.previous();
1.722 + else
1.723 + throw new NoSuchElementException();
1.724 + }
1.725 +
1.726 + public int nextIndex() {
1.727 + return i.nextIndex() - offset;
1.728 + }
1.729 +
1.730 + public int previousIndex() {
1.731 + return i.previousIndex() - offset;
1.732 + }
1.733 +
1.734 + public void remove() {
1.735 + i.remove();
1.736 + SubList.this.modCount = l.modCount;
1.737 + size--;
1.738 + }
1.739 +
1.740 + public void set(E e) {
1.741 + i.set(e);
1.742 + }
1.743 +
1.744 + public void add(E e) {
1.745 + i.add(e);
1.746 + SubList.this.modCount = l.modCount;
1.747 + size++;
1.748 + }
1.749 + };
1.750 + }
1.751 +
1.752 + public List<E> subList(int fromIndex, int toIndex) {
1.753 + return new SubList<>(this, fromIndex, toIndex);
1.754 + }
1.755 +
1.756 + private void rangeCheck(int index) {
1.757 + if (index < 0 || index >= size)
1.758 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1.759 + }
1.760 +
1.761 + private void rangeCheckForAdd(int index) {
1.762 + if (index < 0 || index > size)
1.763 + throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
1.764 + }
1.765 +
1.766 + private String outOfBoundsMsg(int index) {
1.767 + return "Index: "+index+", Size: "+size;
1.768 + }
1.769 +
1.770 + private void checkForComodification() {
1.771 + if (this.modCount != l.modCount)
1.772 + throw new ConcurrentModificationException();
1.773 + }
1.774 +}
1.775 +
1.776 +class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
1.777 + RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
1.778 + super(list, fromIndex, toIndex);
1.779 + }
1.780 +
1.781 + public List<E> subList(int fromIndex, int toIndex) {
1.782 + return new RandomAccessSubList<>(this, fromIndex, toIndex);
1.783 + }
1.784 +}