1. /*
  2. * @(#)AbstractList.java 1.46 04/02/10
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util;
  8. /**
  9. * This class provides a skeletal implementation of the <tt>List</tt>
  10. * interface to minimize the effort required to implement this interface
  11. * backed by a "random access" data store (such as an array). For sequential
  12. * access data (such as a linked list), <tt>AbstractSequentialList</tt> should
  13. * be used in preference to this class.<p>
  14. *
  15. * To implement an unmodifiable list, the programmer needs only to extend this
  16. * class and provide implementations for the <tt>get(int index)</tt> and
  17. * <tt>size()</tt> methods.<p>
  18. *
  19. * To implement a modifiable list, the programmer must additionally override
  20. * the <tt>set(int index, Object element)</tt> method (which otherwise throws
  21. * an <tt>UnsupportedOperationException</tt>. If the list is variable-size
  22. * the programmer must additionally override the <tt>add(int index, Object
  23. * element)</tt> and <tt>remove(int index)</tt> methods.<p>
  24. *
  25. * The programmer should generally provide a void (no argument) and collection
  26. * constructor, as per the recommendation in the <tt>Collection</tt> interface
  27. * specification.<p>
  28. *
  29. * Unlike the other abstract collection implementations, the programmer does
  30. * <i>not</i> have to provide an iterator implementation; the iterator and
  31. * list iterator are implemented by this class, on top the "random access"
  32. * methods: <tt>get(int index)</tt>, <tt>set(int index, Object element)</tt>,
  33. * <tt>set(int index, Object element)</tt>, <tt>add(int index, Object
  34. * element)</tt> and <tt>remove(int index)</tt>.<p>
  35. *
  36. * The documentation for each non-abstract methods in this class describes its
  37. * implementation in detail. Each of these methods may be overridden if the
  38. * collection being implemented admits a more efficient implementation.<p>
  39. *
  40. * This class is a member of the
  41. * <a href="{@docRoot}/../guide/collections/index.html">
  42. * Java Collections Framework</a>.
  43. *
  44. * @author Josh Bloch
  45. * @author Neal Gafter
  46. * @version 1.37, 01/18/03
  47. * @see Collection
  48. * @see List
  49. * @see AbstractSequentialList
  50. * @see AbstractCollection
  51. * @since 1.2
  52. */
  53. public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
  54. /**
  55. * Sole constructor. (For invocation by subclass constructors, typically
  56. * implicit.)
  57. */
  58. protected AbstractList() {
  59. }
  60. /**
  61. * Appends the specified element to the end of this List (optional
  62. * operation). <p>
  63. *
  64. * This implementation calls <tt>add(size(), o)</tt>.<p>
  65. *
  66. * Note that this implementation throws an
  67. * <tt>UnsupportedOperationException</tt> unless <tt>add(int, Object)</tt>
  68. * is overridden.
  69. *
  70. * @param o element to be appended to this list.
  71. *
  72. * @return <tt>true</tt> (as per the general contract of
  73. * <tt>Collection.add</tt>).
  74. *
  75. * @throws UnsupportedOperationException if the <tt>add</tt> method is not
  76. * supported by this Set.
  77. *
  78. * @throws ClassCastException if the class of the specified element
  79. * prevents it from being added to this set.
  80. *
  81. * @throws IllegalArgumentException some aspect of this element prevents
  82. * it from being added to this collection.
  83. */
  84. public boolean add(E o) {
  85. add(size(), o);
  86. return true;
  87. }
  88. /**
  89. * Returns the element at the specified position in this list.
  90. *
  91. * @param index index of element to return.
  92. *
  93. * @return the element at the specified position in this list.
  94. * @throws IndexOutOfBoundsException if the given index is out of range
  95. * (<tt>index < 0 || index >= size()</tt>).
  96. */
  97. abstract public E get(int index);
  98. /**
  99. * Replaces the element at the specified position in this list with the
  100. * specified element (optional operation). <p>
  101. *
  102. * This implementation always throws an
  103. * <tt>UnsupportedOperationException</tt>.
  104. *
  105. * @param index index of element to replace.
  106. * @param element element to be stored at the specified position.
  107. * @return the element previously at the specified position.
  108. *
  109. * @throws UnsupportedOperationException if the <tt>set</tt> method is not
  110. * supported by this List.
  111. * @throws ClassCastException if the class of the specified element
  112. * prevents it from being added to this list.
  113. * @throws IllegalArgumentException if some aspect of the specified
  114. * element prevents it from being added to this list.
  115. *
  116. * @throws IndexOutOfBoundsException if the specified index is out of
  117. * range (<tt>index < 0 || index >= size()</tt>).
  118. */
  119. public E set(int index, E element) {
  120. throw new UnsupportedOperationException();
  121. }
  122. /**
  123. * Inserts the specified element at the specified position in this list
  124. * (optional operation). Shifts the element currently at that position
  125. * (if any) and any subsequent elements to the right (adds one to their
  126. * indices).<p>
  127. *
  128. * This implementation always throws an UnsupportedOperationException.
  129. *
  130. * @param index index at which the specified element is to be inserted.
  131. * @param element element to be inserted.
  132. *
  133. * @throws UnsupportedOperationException if the <tt>add</tt> method is not
  134. * supported by this list.
  135. * @throws ClassCastException if the class of the specified element
  136. * prevents it from being added to this list.
  137. * @throws IllegalArgumentException if some aspect of the specified
  138. * element prevents it from being added to this list.
  139. * @throws IndexOutOfBoundsException index is out of range (<tt>index <
  140. * 0 || index > size()</tt>).
  141. */
  142. public void add(int index, E element) {
  143. throw new UnsupportedOperationException();
  144. }
  145. /**
  146. * Removes the element at the specified position in this list (optional
  147. * operation). Shifts any subsequent elements to the left (subtracts one
  148. * from their indices). Returns the element that was removed from the
  149. * list.<p>
  150. *
  151. * This implementation always throws an
  152. * <tt>UnsupportedOperationException</tt>.
  153. *
  154. * @param index the index of the element to remove.
  155. * @return the element previously at the specified position.
  156. *
  157. * @throws UnsupportedOperationException if the <tt>remove</tt> method is
  158. * not supported by this list.
  159. * @throws IndexOutOfBoundsException if the specified index is out of
  160. * range (<tt>index < 0 || index >= size()</tt>).
  161. */
  162. public E remove(int index) {
  163. throw new UnsupportedOperationException();
  164. }
  165. // Search Operations
  166. /**
  167. * Returns the index in this list of the first occurence of the specified
  168. * element, or -1 if the list does not contain this element. More
  169. * formally, returns the lowest index <tt>i</tt> such that <tt>(o==null ?
  170. * get(i)==null : o.equals(get(i)))</tt>, or -1 if there is no such
  171. * index.<p>
  172. *
  173. * This implementation first gets a list iterator (with
  174. * <tt>listIterator()</tt>). Then, it iterates over the list until the
  175. * specified element is found or the end of the list is reached.
  176. *
  177. * @param o element to search for.
  178. *
  179. * @return the index in this List of the first occurence of the specified
  180. * element, or -1 if the List does not contain this element.
  181. */
  182. public int indexOf(Object o) {
  183. ListIterator<E> e = listIterator();
  184. if (o==null) {
  185. while (e.hasNext())
  186. if (e.next()==null)
  187. return e.previousIndex();
  188. } else {
  189. while (e.hasNext())
  190. if (o.equals(e.next()))
  191. return e.previousIndex();
  192. }
  193. return -1;
  194. }
  195. /**
  196. * Returns the index in this list of the last occurence of the specified
  197. * element, or -1 if the list does not contain this element. More
  198. * formally, returns the highest index <tt>i</tt> such that <tt>(o==null ?
  199. * get(i)==null : o.equals(get(i)))</tt>, or -1 if there is no such
  200. * index.<p>
  201. *
  202. * This implementation first gets a list iterator that points to the end
  203. * of the list (with listIterator(size())). Then, it iterates backwards
  204. * over the list until the specified element is found, or the beginning of
  205. * the list is reached.
  206. *
  207. * @param o element to search for.
  208. *
  209. * @return the index in this list of the last occurence of the specified
  210. * element, or -1 if the list does not contain this element.
  211. */
  212. public int lastIndexOf(Object o) {
  213. ListIterator<E> e = listIterator(size());
  214. if (o==null) {
  215. while (e.hasPrevious())
  216. if (e.previous()==null)
  217. return e.nextIndex();
  218. } else {
  219. while (e.hasPrevious())
  220. if (o.equals(e.previous()))
  221. return e.nextIndex();
  222. }
  223. return -1;
  224. }
  225. // Bulk Operations
  226. /**
  227. * Removes all of the elements from this collection (optional operation).
  228. * The collection will be empty after this call returns (unless it throws
  229. * an exception).<p>
  230. *
  231. * This implementation calls <tt>removeRange(0, size())</tt>.<p>
  232. *
  233. * Note that this implementation throws an
  234. * <tt>UnsupportedOperationException</tt> unless <tt>remove(int
  235. * index)</tt> or <tt>removeRange(int fromIndex, int toIndex)</tt> is
  236. * overridden.
  237. *
  238. * @throws UnsupportedOperationException if the <tt>clear</tt> method is
  239. * not supported by this Collection.
  240. */
  241. public void clear() {
  242. removeRange(0, size());
  243. }
  244. /**
  245. * Inserts all of the elements in the specified collection into this list
  246. * at the specified position (optional operation). Shifts the element
  247. * currently at that position (if any) and any subsequent elements to the
  248. * right (increases their indices). The new elements will appear in the
  249. * list in the order that they are returned by the specified collection's
  250. * iterator. The behavior of this operation is unspecified if the
  251. * specified collection is modified while the operation is in progress.
  252. * (Note that this will occur if the specified collection is this list,
  253. * and it's nonempty.)<p>
  254. *
  255. * This implementation gets an iterator over the specified collection and
  256. * iterates over it, inserting the elements obtained from the iterator
  257. * into this list at the appropriate position, one at a time, using
  258. * <tt>add(int, Object)</tt>. Many implementations will override this
  259. * method for efficiency.<p>
  260. *
  261. * Note that this implementation throws an
  262. * <tt>UnsupportedOperationException</tt> unless <tt>add(int, Object)</tt>
  263. * is overridden.
  264. *
  265. * @return <tt>true</tt> if this list changed as a result of the call.
  266. * @param index index at which to insert the first element from the
  267. * specified collection.
  268. * @param c elements to be inserted into this List.
  269. *
  270. * @throws UnsupportedOperationException if the <tt>addAll</tt> method is
  271. * not supported by this list.
  272. *
  273. * @throws ClassCastException if the class of an element of the specified
  274. * collection prevents it from being added to this List.
  275. *
  276. * @throws IllegalArgumentException some aspect an element of the
  277. * specified collection prevents it from being added to this
  278. * List.
  279. *
  280. * @throws IndexOutOfBoundsException index out of range (<tt>index < 0
  281. * || index > size()</tt>).
  282. *
  283. * @throws NullPointerException if the specified collection is null.
  284. */
  285. public boolean addAll(int index, Collection<? extends E> c) {
  286. boolean modified = false;
  287. Iterator<? extends E> e = c.iterator();
  288. while (e.hasNext()) {
  289. add(index++, e.next());
  290. modified = true;
  291. }
  292. return modified;
  293. }
  294. // Iterators
  295. /**
  296. * Returns an iterator over the elements in this list in proper
  297. * sequence. <p>
  298. *
  299. * This implementation returns a straightforward implementation of the
  300. * iterator interface, relying on the backing list's <tt>size()</tt>,
  301. * <tt>get(int)</tt>, and <tt>remove(int)</tt> methods.<p>
  302. *
  303. * Note that the iterator returned by this method will throw an
  304. * <tt>UnsupportedOperationException</tt> in response to its
  305. * <tt>remove</tt> method unless the list's <tt>remove(int)</tt> method is
  306. * overridden.<p>
  307. *
  308. * This implementation can be made to throw runtime exceptions in the face
  309. * of concurrent modification, as described in the specification for the
  310. * (protected) <tt>modCount</tt> field.
  311. *
  312. * @return an iterator over the elements in this list in proper sequence.
  313. *
  314. * @see #modCount
  315. */
  316. public Iterator<E> iterator() {
  317. return new Itr();
  318. }
  319. /**
  320. * Returns an iterator of the elements in this list (in proper sequence).
  321. * This implementation returns <tt>listIterator(0)</tt>.
  322. *
  323. * @return an iterator of the elements in this list (in proper sequence).
  324. *
  325. * @see #listIterator(int)
  326. */
  327. public ListIterator<E> listIterator() {
  328. return listIterator(0);
  329. }
  330. /**
  331. * Returns a list iterator of the elements in this list (in proper
  332. * sequence), starting at the specified position in the list. The
  333. * specified index indicates the first element that would be returned by
  334. * an initial call to the <tt>next</tt> method. An initial call to
  335. * the <tt>previous</tt> method would return the element with the
  336. * specified index minus one.<p>
  337. *
  338. * This implementation returns a straightforward implementation of the
  339. * <tt>ListIterator</tt> interface that extends the implementation of the
  340. * <tt>Iterator</tt> interface returned by the <tt>iterator()</tt> method.
  341. * The <tt>ListIterator</tt> implementation relies on the backing list's
  342. * <tt>get(int)</tt>, <tt>set(int, Object)</tt>, <tt>add(int, Object)</tt>
  343. * and <tt>remove(int)</tt> methods.<p>
  344. *
  345. * Note that the list iterator returned by this implementation will throw
  346. * an <tt>UnsupportedOperationException</tt> in response to its
  347. * <tt>remove</tt>, <tt>set</tt> and <tt>add</tt> methods unless the
  348. * list's <tt>remove(int)</tt>, <tt>set(int, Object)</tt>, and
  349. * <tt>add(int, Object)</tt> methods are overridden.<p>
  350. *
  351. * This implementation can be made to throw runtime exceptions in the
  352. * face of concurrent modification, as described in the specification for
  353. * the (protected) <tt>modCount</tt> field.
  354. *
  355. * @param index index of the first element to be returned from the list
  356. * iterator (by a call to the <tt>next</tt> method).
  357. *
  358. * @return a list iterator of the elements in this list (in proper
  359. * sequence), starting at the specified position in the list.
  360. *
  361. * @throws IndexOutOfBoundsException if the specified index is out of
  362. * range (<tt>index < 0 || index > size()</tt>).
  363. *
  364. * @see #modCount
  365. */
  366. public ListIterator<E> listIterator(final int index) {
  367. if (index<0 || index>size())
  368. throw new IndexOutOfBoundsException("Index: "+index);
  369. return new ListItr(index);
  370. }
  371. private class Itr implements Iterator<E> {
  372. /**
  373. * Index of element to be returned by subsequent call to next.
  374. */
  375. int cursor = 0;
  376. /**
  377. * Index of element returned by most recent call to next or
  378. * previous. Reset to -1 if this element is deleted by a call
  379. * to remove.
  380. */
  381. int lastRet = -1;
  382. /**
  383. * The modCount value that the iterator believes that the backing
  384. * List should have. If this expectation is violated, the iterator
  385. * has detected concurrent modification.
  386. */
  387. int expectedModCount = modCount;
  388. public boolean hasNext() {
  389. return cursor != size();
  390. }
  391. public E next() {
  392. checkForComodification();
  393. try {
  394. E next = get(cursor);
  395. lastRet = cursor++;
  396. return next;
  397. } catch(IndexOutOfBoundsException e) {
  398. checkForComodification();
  399. throw new NoSuchElementException();
  400. }
  401. }
  402. public void remove() {
  403. if (lastRet == -1)
  404. throw new IllegalStateException();
  405. checkForComodification();
  406. try {
  407. AbstractList.this.remove(lastRet);
  408. if (lastRet < cursor)
  409. cursor--;
  410. lastRet = -1;
  411. expectedModCount = modCount;
  412. } catch(IndexOutOfBoundsException e) {
  413. throw new ConcurrentModificationException();
  414. }
  415. }
  416. final void checkForComodification() {
  417. if (modCount != expectedModCount)
  418. throw new ConcurrentModificationException();
  419. }
  420. }
  421. private class ListItr extends Itr implements ListIterator<E> {
  422. ListItr(int index) {
  423. cursor = index;
  424. }
  425. public boolean hasPrevious() {
  426. return cursor != 0;
  427. }
  428. public E previous() {
  429. checkForComodification();
  430. try {
  431. int i = cursor - 1;
  432. E previous = get(i);
  433. lastRet = cursor = i;
  434. return previous;
  435. } catch(IndexOutOfBoundsException e) {
  436. checkForComodification();
  437. throw new NoSuchElementException();
  438. }
  439. }
  440. public int nextIndex() {
  441. return cursor;
  442. }
  443. public int previousIndex() {
  444. return cursor-1;
  445. }
  446. public void set(E o) {
  447. if (lastRet == -1)
  448. throw new IllegalStateException();
  449. checkForComodification();
  450. try {
  451. AbstractList.this.set(lastRet, o);
  452. expectedModCount = modCount;
  453. } catch(IndexOutOfBoundsException e) {
  454. throw new ConcurrentModificationException();
  455. }
  456. }
  457. public void add(E o) {
  458. checkForComodification();
  459. try {
  460. AbstractList.this.add(cursor++, o);
  461. lastRet = -1;
  462. expectedModCount = modCount;
  463. } catch(IndexOutOfBoundsException e) {
  464. throw new ConcurrentModificationException();
  465. }
  466. }
  467. }
  468. /**
  469. * Returns a view of the portion of this list between <tt>fromIndex</tt>,
  470. * inclusive, and <tt>toIndex</tt>, exclusive. (If <tt>fromIndex</tt> and
  471. * <tt>toIndex</tt> are equal, the returned list is empty.) The returned
  472. * list is backed by this list, so changes in the returned list are
  473. * reflected in this list, and vice-versa. The returned list supports all
  474. * of the optional list operations supported by this list.<p>
  475. *
  476. * This method eliminates the need for explicit range operations (of the
  477. * sort that commonly exist for arrays). Any operation that expects a
  478. * list can be used as a range operation by operating on a subList view
  479. * instead of a whole list. For example, the following idiom removes a
  480. * range of elements from a list:
  481. * <pre>
  482. * list.subList(from, to).clear();
  483. * </pre>
  484. * Similar idioms may be constructed for <tt>indexOf</tt> and
  485. * <tt>lastIndexOf</tt>, and all of the algorithms in the
  486. * <tt>Collections</tt> class can be applied to a subList.<p>
  487. *
  488. * The semantics of the list returned by this method become undefined if
  489. * the backing list (i.e., this list) is <i>structurally modified</i> in
  490. * any way other than via the returned list. (Structural modifications are
  491. * those that change the size of the list, or otherwise perturb it in such
  492. * a fashion that iterations in progress may yield incorrect results.)<p>
  493. *
  494. * This implementation returns a list that subclasses
  495. * <tt>AbstractList</tt>. The subclass stores, in private fields, the
  496. * offset of the subList within the backing list, the size of the subList
  497. * (which can change over its lifetime), and the expected
  498. * <tt>modCount</tt> value of the backing list. There are two variants
  499. * of the subclass, one of which implements <tt>RandomAccess</tt>.
  500. * If this list implements <tt>RandomAccess</tt> the returned list will
  501. * be an instance of the subclass that implements <tt>RandomAccess</tt>.<p>
  502. *
  503. * The subclass's <tt>set(int, Object)</tt>, <tt>get(int)</tt>,
  504. * <tt>add(int, Object)</tt>, <tt>remove(int)</tt>, <tt>addAll(int,
  505. * Collection)</tt> and <tt>removeRange(int, int)</tt> methods all
  506. * delegate to the corresponding methods on the backing abstract list,
  507. * after bounds-checking the index and adjusting for the offset. The
  508. * <tt>addAll(Collection c)</tt> method merely returns <tt>addAll(size,
  509. * c)</tt>.<p>
  510. *
  511. * The <tt>listIterator(int)</tt> method returns a "wrapper object" over a
  512. * list iterator on the backing list, which is created with the
  513. * corresponding method on the backing list. The <tt>iterator</tt> method
  514. * merely returns <tt>listIterator()</tt>, and the <tt>size</tt> method
  515. * merely returns the subclass's <tt>size</tt> field.<p>
  516. *
  517. * All methods first check to see if the actual <tt>modCount</tt> of the
  518. * backing list is equal to its expected value, and throw a
  519. * <tt>ConcurrentModificationException</tt> if it is not.
  520. *
  521. * @param fromIndex low endpoint (inclusive) of the subList.
  522. * @param toIndex high endpoint (exclusive) of the subList.
  523. * @return a view of the specified range within this list.
  524. * @throws IndexOutOfBoundsException endpoint index value out of range
  525. * <tt>(fromIndex < 0 || toIndex > size)</tt>
  526. * @throws IllegalArgumentException endpoint indices out of order
  527. * <tt>(fromIndex > toIndex)</tt> */
  528. public List<E> subList(int fromIndex, int toIndex) {
  529. return (this instanceof RandomAccess ?
  530. new RandomAccessSubList<E>(this, fromIndex, toIndex) :
  531. new SubList<E>(this, fromIndex, toIndex));
  532. }
  533. // Comparison and hashing
  534. /**
  535. * Compares the specified object with this list for equality. Returns
  536. * <tt>true</tt> if and only if the specified object is also a list, both
  537. * lists have the same size, and all corresponding pairs of elements in
  538. * the two lists are <i>equal</i>. (Two elements <tt>e1</tt> and
  539. * <tt>e2</tt> are <i>equal</i> if <tt>(e1==null ? e2==null :
  540. * e1.equals(e2))</tt>.) In other words, two lists are defined to be
  541. * equal if they contain the same elements in the same order.<p>
  542. *
  543. * This implementation first checks if the specified object is this
  544. * list. If so, it returns <tt>true</tt> if not, it checks if the
  545. * specified object is a list. If not, it returns <tt>false</tt> if so,
  546. * it iterates over both lists, comparing corresponding pairs of elements.
  547. * If any comparison returns <tt>false</tt>, this method returns
  548. * <tt>false</tt>. If either iterator runs out of elements before the
  549. * other it returns <tt>false</tt> (as the lists are of unequal length);
  550. * otherwise it returns <tt>true</tt> when the iterations complete.
  551. *
  552. * @param o the object to be compared for equality with this list.
  553. *
  554. * @return <tt>true</tt> if the specified object is equal to this list.
  555. */
  556. public boolean equals(Object o) {
  557. if (o == this)
  558. return true;
  559. if (!(o instanceof List))
  560. return false;
  561. ListIterator<E> e1 = listIterator();
  562. ListIterator e2 = ((List) o).listIterator();
  563. while(e1.hasNext() && e2.hasNext()) {
  564. E o1 = e1.next();
  565. Object o2 = e2.next();
  566. if (!(o1==null ? o2==null : o1.equals(o2)))
  567. return false;
  568. }
  569. return !(e1.hasNext() || e2.hasNext());
  570. }
  571. /**
  572. * Returns the hash code value for this list. <p>
  573. *
  574. * This implementation uses exactly the code that is used to define the
  575. * list hash function in the documentation for the <tt>List.hashCode</tt>
  576. * method.
  577. *
  578. * @return the hash code value for this list.
  579. */
  580. public int hashCode() {
  581. int hashCode = 1;
  582. Iterator<E> i = iterator();
  583. while (i.hasNext()) {
  584. E obj = i.next();
  585. hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
  586. }
  587. return hashCode;
  588. }
  589. /**
  590. * Removes from this list all of the elements whose index is between
  591. * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
  592. * Shifts any succeeding elements to the left (reduces their index). This
  593. * call shortens the ArrayList by <tt>(toIndex - fromIndex)</tt>
  594. * elements. (If <tt>toIndex==fromIndex</tt>, this operation has no
  595. * effect.)<p>
  596. *
  597. * This method is called by the <tt>clear</tt> operation on this list
  598. * and its subLists. Overriding this method to take advantage of
  599. * the internals of the list implementation can <i>substantially</i>
  600. * improve the performance of the <tt>clear</tt> operation on this list
  601. * and its subLists.<p>
  602. *
  603. * This implementation gets a list iterator positioned before
  604. * <tt>fromIndex</tt>, and repeatedly calls <tt>ListIterator.next</tt>
  605. * followed by <tt>ListIterator.remove</tt> until the entire range has
  606. * been removed. <b>Note: if <tt>ListIterator.remove</tt> requires linear
  607. * time, this implementation requires quadratic time.</b>
  608. *
  609. * @param fromIndex index of first element to be removed.
  610. * @param toIndex index after last element to be removed.
  611. */
  612. protected void removeRange(int fromIndex, int toIndex) {
  613. ListIterator<E> it = listIterator(fromIndex);
  614. for (int i=0, n=toIndex-fromIndex; i<n; i++) {
  615. it.next();
  616. it.remove();
  617. }
  618. }
  619. /**
  620. * The number of times this list has been <i>structurally modified</i>.
  621. * Structural modifications are those that change the size of the
  622. * list, or otherwise perturb it in such a fashion that iterations in
  623. * progress may yield incorrect results.<p>
  624. *
  625. * This field is used by the iterator and list iterator implementation
  626. * returned by the <tt>iterator</tt> and <tt>listIterator</tt> methods.
  627. * If the value of this field changes unexpectedly, the iterator (or list
  628. * iterator) will throw a <tt>ConcurrentModificationException</tt> in
  629. * response to the <tt>next</tt>, <tt>remove</tt>, <tt>previous</tt>,
  630. * <tt>set</tt> or <tt>add</tt> operations. This provides
  631. * <i>fail-fast</i> behavior, rather than non-deterministic behavior in
  632. * the face of concurrent modification during iteration.<p>
  633. *
  634. * <b>Use of this field by subclasses is optional.</b> If a subclass
  635. * wishes to provide fail-fast iterators (and list iterators), then it
  636. * merely has to increment this field in its <tt>add(int, Object)</tt> and
  637. * <tt>remove(int)</tt> methods (and any other methods that it overrides
  638. * that result in structural modifications to the list). A single call to
  639. * <tt>add(int, Object)</tt> or <tt>remove(int)</tt> must add no more than
  640. * one to this field, or the iterators (and list iterators) will throw
  641. * bogus <tt>ConcurrentModificationExceptions</tt>. If an implementation
  642. * does not wish to provide fail-fast iterators, this field may be
  643. * ignored.
  644. */
  645. protected transient int modCount = 0;
  646. }
  647. class SubList<E> extends AbstractList<E> {
  648. private AbstractList<E> l;
  649. private int offset;
  650. private int size;
  651. private int expectedModCount;
  652. SubList(AbstractList<E> list, int fromIndex, int toIndex) {
  653. if (fromIndex < 0)
  654. throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
  655. if (toIndex > list.size())
  656. throw new IndexOutOfBoundsException("toIndex = " + toIndex);
  657. if (fromIndex > toIndex)
  658. throw new IllegalArgumentException("fromIndex(" + fromIndex +
  659. ") > toIndex(" + toIndex + ")");
  660. l = list;
  661. offset = fromIndex;
  662. size = toIndex - fromIndex;
  663. expectedModCount = l.modCount;
  664. }
  665. public E set(int index, E element) {
  666. rangeCheck(index);
  667. checkForComodification();
  668. return l.set(index+offset, element);
  669. }
  670. public E get(int index) {
  671. rangeCheck(index);
  672. checkForComodification();
  673. return l.get(index+offset);
  674. }
  675. public int size() {
  676. checkForComodification();
  677. return size;
  678. }
  679. public void add(int index, E element) {
  680. if (index<0 || index>size)
  681. throw new IndexOutOfBoundsException();
  682. checkForComodification();
  683. l.add(index+offset, element);
  684. expectedModCount = l.modCount;
  685. size++;
  686. modCount++;
  687. }
  688. public E remove(int index) {
  689. rangeCheck(index);
  690. checkForComodification();
  691. E result = l.remove(index+offset);
  692. expectedModCount = l.modCount;
  693. size--;
  694. modCount++;
  695. return result;
  696. }
  697. protected void removeRange(int fromIndex, int toIndex) {
  698. checkForComodification();
  699. l.removeRange(fromIndex+offset, toIndex+offset);
  700. expectedModCount = l.modCount;
  701. size -= (toIndex-fromIndex);
  702. modCount++;
  703. }
  704. public boolean addAll(Collection<? extends E> c) {
  705. return addAll(size, c);
  706. }
  707. public boolean addAll(int index, Collection<? extends E> c) {
  708. if (index<0 || index>size)
  709. throw new IndexOutOfBoundsException(
  710. "Index: "+index+", Size: "+size);
  711. int cSize = c.size();
  712. if (cSize==0)
  713. return false;
  714. checkForComodification();
  715. l.addAll(offset+index, c);
  716. expectedModCount = l.modCount;
  717. size += cSize;
  718. modCount++;
  719. return true;
  720. }
  721. public Iterator<E> iterator() {
  722. return listIterator();
  723. }
  724. public ListIterator<E> listIterator(final int index) {
  725. checkForComodification();
  726. if (index<0 || index>size)
  727. throw new IndexOutOfBoundsException(
  728. "Index: "+index+", Size: "+size);
  729. return new ListIterator<E>() {
  730. private ListIterator<E> i = l.listIterator(index+offset);
  731. public boolean hasNext() {
  732. return nextIndex() < size;
  733. }
  734. public E next() {
  735. if (hasNext())
  736. return i.next();
  737. else
  738. throw new NoSuchElementException();
  739. }
  740. public boolean hasPrevious() {
  741. return previousIndex() >= 0;
  742. }
  743. public E previous() {
  744. if (hasPrevious())
  745. return i.previous();
  746. else
  747. throw new NoSuchElementException();
  748. }
  749. public int nextIndex() {
  750. return i.nextIndex() - offset;
  751. }
  752. public int previousIndex() {
  753. return i.previousIndex() - offset;
  754. }
  755. public void remove() {
  756. i.remove();
  757. expectedModCount = l.modCount;
  758. size--;
  759. modCount++;
  760. }
  761. public void set(E o) {
  762. i.set(o);
  763. }
  764. public void add(E o) {
  765. i.add(o);
  766. expectedModCount = l.modCount;
  767. size++;
  768. modCount++;
  769. }
  770. };
  771. }
  772. public List<E> subList(int fromIndex, int toIndex) {
  773. return new SubList<E>(this, fromIndex, toIndex);
  774. }
  775. private void rangeCheck(int index) {
  776. if (index<0 || index>=size)
  777. throw new IndexOutOfBoundsException("Index: "+index+
  778. ",Size: "+size);
  779. }
  780. private void checkForComodification() {
  781. if (l.modCount != expectedModCount)
  782. throw new ConcurrentModificationException();
  783. }
  784. }
  785. class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
  786. RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
  787. super(list, fromIndex, toIndex);
  788. }
  789. public List<E> subList(int fromIndex, int toIndex) {
  790. return new RandomAccessSubList<E>(this, fromIndex, toIndex);
  791. }
  792. }