AbstractList.java 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  1. /* AbstractList.java -- Abstract implementation of most of List
  2. Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005
  3. Free Software Foundation, Inc.
  4. This file is part of GNU Classpath.
  5. GNU Classpath is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9. GNU Classpath is distributed in the hope that it will be useful, but
  10. WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GNU Classpath; see the file COPYING. If not, write to the
  15. Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  16. 02110-1301 USA.
  17. Linking this library statically or dynamically with other modules is
  18. making a combined work based on this library. Thus, the terms and
  19. conditions of the GNU General Public License cover the whole
  20. combination.
  21. As a special exception, the copyright holders of this library give you
  22. permission to link this library with independent modules to produce an
  23. executable, regardless of the license terms of these independent
  24. modules, and to copy and distribute the resulting executable under
  25. terms of your choice, provided that you also meet, for each linked
  26. independent module, the terms and conditions of the license of that
  27. module. An independent module is a module which is not derived from
  28. or based on this library. If you modify this library, you may extend
  29. this exception to your version of the library, but you are not
  30. obligated to do so. If you do not wish to do so, delete this
  31. exception statement from your version. */
  32. package java.util;
  33. /**
  34. * A basic implementation of most of the methods in the List interface to make
  35. * it easier to create a List based on a random-access data structure. If
  36. * the list is sequential (such as a linked list), use AbstractSequentialList.
  37. * To create an unmodifiable list, it is only necessary to override the
  38. * size() and get(int) methods (this contrasts with all other abstract
  39. * collection classes which require an iterator to be provided). To make the
  40. * list modifiable, the set(int, Object) method should also be overridden, and
  41. * to make the list resizable, the add(int, Object) and remove(int) methods
  42. * should be overridden too. Other methods should be overridden if the
  43. * backing data structure allows for a more efficient implementation.
  44. * The precise implementation used by AbstractList is documented, so that
  45. * subclasses can tell which methods could be implemented more efficiently.
  46. * <p>
  47. *
  48. * As recommended by Collection and List, the subclass should provide at
  49. * least a no-argument and a Collection constructor. This class is not
  50. * synchronized.
  51. *
  52. * @author Original author unknown
  53. * @author Bryce McKinlay
  54. * @author Eric Blake (ebb9@email.byu.edu)
  55. * @see Collection
  56. * @see List
  57. * @see AbstractSequentialList
  58. * @see AbstractCollection
  59. * @see ListIterator
  60. * @since 1.2
  61. * @status updated to 1.4
  62. */
  63. public abstract class AbstractList<E>
  64. extends AbstractCollection<E>
  65. implements List<E>
  66. {
  67. /**
  68. * A count of the number of structural modifications that have been made to
  69. * the list (that is, insertions and removals). Structural modifications
  70. * are ones which change the list size or affect how iterations would
  71. * behave. This field is available for use by Iterator and ListIterator,
  72. * in order to throw a {@link ConcurrentModificationException} in response
  73. * to the next operation on the iterator. This <i>fail-fast</i> behavior
  74. * saves the user from many subtle bugs otherwise possible from concurrent
  75. * modification during iteration.
  76. * <p>
  77. *
  78. * To make lists fail-fast, increment this field by just 1 in the
  79. * <code>add(int, Object)</code> and <code>remove(int)</code> methods.
  80. * Otherwise, this field may be ignored.
  81. */
  82. protected transient int modCount;
  83. /**
  84. * The main constructor, for use by subclasses.
  85. */
  86. protected AbstractList()
  87. {
  88. }
  89. /**
  90. * Returns the elements at the specified position in the list.
  91. *
  92. * @param index the element to return
  93. * @return the element at that position
  94. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
  95. */
  96. public abstract E get(int index);
  97. /**
  98. * Insert an element into the list at a given position (optional operation).
  99. * This shifts all existing elements from that position to the end one
  100. * index to the right. This version of add has no return, since it is
  101. * assumed to always succeed if there is no exception. This implementation
  102. * always throws UnsupportedOperationException, and must be overridden to
  103. * make a modifiable List. If you want fail-fast iterators, be sure to
  104. * increment modCount when overriding this.
  105. *
  106. * @param index the location to insert the item
  107. * @param o the object to insert
  108. * @throws UnsupportedOperationException if this list does not support the
  109. * add operation
  110. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
  111. * @throws ClassCastException if o cannot be added to this list due to its
  112. * type
  113. * @throws IllegalArgumentException if o cannot be added to this list for
  114. * some other reason
  115. * @see #modCount
  116. */
  117. public void add(int index, E o)
  118. {
  119. throw new UnsupportedOperationException();
  120. }
  121. /**
  122. * Add an element to the end of the list (optional operation). If the list
  123. * imposes restraints on what can be inserted, such as no null elements,
  124. * this should be documented. This implementation calls
  125. * <code>add(size(), o);</code>, and will fail if that version does.
  126. *
  127. * @param o the object to add
  128. * @return true, as defined by Collection for a modified list
  129. * @throws UnsupportedOperationException if this list does not support the
  130. * add operation
  131. * @throws ClassCastException if o cannot be added to this list due to its
  132. * type
  133. * @throws IllegalArgumentException if o cannot be added to this list for
  134. * some other reason
  135. * @see #add(int, Object)
  136. */
  137. public boolean add(E o)
  138. {
  139. add(size(), o);
  140. return true;
  141. }
  142. /**
  143. * Insert the contents of a collection into the list at a given position
  144. * (optional operation). Shift all elements at that position to the right
  145. * by the number of elements inserted. This operation is undefined if
  146. * this list is modified during the operation (for example, if you try
  147. * to insert a list into itself). This implementation uses the iterator of
  148. * the collection, repeatedly calling add(int, Object); this will fail
  149. * if add does. This can often be made more efficient.
  150. *
  151. * @param index the location to insert the collection
  152. * @param c the collection to insert
  153. * @return true if the list was modified by this action, that is, if c is
  154. * non-empty
  155. * @throws UnsupportedOperationException if this list does not support the
  156. * addAll operation
  157. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
  158. * @throws ClassCastException if some element of c cannot be added to this
  159. * list due to its type
  160. * @throws IllegalArgumentException if some element of c cannot be added
  161. * to this list for some other reason
  162. * @throws NullPointerException if the specified collection is null
  163. * @see #add(int, Object)
  164. */
  165. public boolean addAll(int index, Collection<? extends E> c)
  166. {
  167. Iterator<? extends E> itr = c.iterator();
  168. int size = c.size();
  169. for (int pos = size; pos > 0; pos--)
  170. add(index++, itr.next());
  171. return size > 0;
  172. }
  173. /**
  174. * Clear the list, such that a subsequent call to isEmpty() would return
  175. * true (optional operation). This implementation calls
  176. * <code>removeRange(0, size())</code>, so it will fail unless remove
  177. * or removeRange is overridden.
  178. *
  179. * @throws UnsupportedOperationException if this list does not support the
  180. * clear operation
  181. * @see #remove(int)
  182. * @see #removeRange(int, int)
  183. */
  184. public void clear()
  185. {
  186. removeRange(0, size());
  187. }
  188. /**
  189. * Test whether this list is equal to another object. A List is defined to be
  190. * equal to an object if and only if that object is also a List, and the two
  191. * lists have the same sequence. Two lists l1 and l2 are equal if and only
  192. * if <code>l1.size() == l2.size()</code>, and for every integer n between 0
  193. * and <code>l1.size() - 1</code> inclusive, <code>l1.get(n) == null ?
  194. * l2.get(n) == null : l1.get(n).equals(l2.get(n))</code>.
  195. * <p>
  196. *
  197. * This implementation returns true if the object is this, or false if the
  198. * object is not a List. Otherwise, it iterates over both lists (with
  199. * iterator()), returning false if two elements compare false or one list
  200. * is shorter, and true if the iteration completes successfully.
  201. *
  202. * @param o the object to test for equality with this list
  203. * @return true if o is equal to this list
  204. * @see Object#equals(Object)
  205. * @see #hashCode()
  206. */
  207. public boolean equals(Object o)
  208. {
  209. if (o == this)
  210. return true;
  211. if (! (o instanceof List))
  212. return false;
  213. int size = size();
  214. if (size != ((List) o).size())
  215. return false;
  216. Iterator<E> itr1 = iterator();
  217. Iterator itr2 = ((List) o).iterator();
  218. while (--size >= 0)
  219. if (! equals(itr1.next(), itr2.next()))
  220. return false;
  221. return true;
  222. }
  223. /**
  224. * Obtains a hash code for this list. In order to obey the general
  225. * contract of the hashCode method of class Object, this value is
  226. * calculated as follows:
  227. *
  228. <pre>hashCode = 1;
  229. Iterator i = list.iterator();
  230. while (i.hasNext())
  231. {
  232. Object obj = i.next();
  233. hashCode = 31 * hashCode + (obj == null ? 0 : obj.hashCode());
  234. }</pre>
  235. *
  236. * This ensures that the general contract of Object.hashCode() is adhered to.
  237. *
  238. * @return the hash code of this list
  239. *
  240. * @see Object#hashCode()
  241. * @see #equals(Object)
  242. */
  243. public int hashCode()
  244. {
  245. int hashCode = 1;
  246. Iterator<E> itr = iterator();
  247. int pos = size();
  248. while (--pos >= 0)
  249. hashCode = 31 * hashCode + hashCode(itr.next());
  250. return hashCode;
  251. }
  252. /**
  253. * Obtain the first index at which a given object is to be found in this
  254. * list. This implementation follows a listIterator() until a match is found,
  255. * or returns -1 if the list end is reached.
  256. *
  257. * @param o the object to search for
  258. * @return the least integer n such that <code>o == null ? get(n) == null :
  259. * o.equals(get(n))</code>, or -1 if there is no such index
  260. */
  261. public int indexOf(Object o)
  262. {
  263. ListIterator<E> itr = listIterator();
  264. int size = size();
  265. for (int pos = 0; pos < size; pos++)
  266. if (equals(o, itr.next()))
  267. return pos;
  268. return -1;
  269. }
  270. /**
  271. * Obtain an Iterator over this list, whose sequence is the list order.
  272. * This implementation uses size(), get(int), and remove(int) of the
  273. * backing list, and does not support remove unless the list does. This
  274. * implementation is fail-fast if you correctly maintain modCount.
  275. * Also, this implementation is specified by Sun to be distinct from
  276. * listIterator, although you could easily implement it as
  277. * <code>return listIterator(0)</code>.
  278. *
  279. * @return an Iterator over the elements of this list, in order
  280. * @see #modCount
  281. */
  282. public Iterator<E> iterator()
  283. {
  284. // Bah, Sun's implementation forbids using listIterator(0).
  285. return new Iterator<E>()
  286. {
  287. private int pos = 0;
  288. private int size = size();
  289. private int last = -1;
  290. private int knownMod = modCount;
  291. // This will get inlined, since it is private.
  292. /**
  293. * Checks for modifications made to the list from
  294. * elsewhere while iteration is in progress.
  295. *
  296. * @throws ConcurrentModificationException if the
  297. * list has been modified elsewhere.
  298. */
  299. private void checkMod()
  300. {
  301. if (knownMod != modCount)
  302. throw new ConcurrentModificationException();
  303. }
  304. /**
  305. * Tests to see if there are any more objects to
  306. * return.
  307. *
  308. * @return True if the end of the list has not yet been
  309. * reached.
  310. */
  311. public boolean hasNext()
  312. {
  313. return pos < size;
  314. }
  315. /**
  316. * Retrieves the next object from the list.
  317. *
  318. * @return The next object.
  319. * @throws NoSuchElementException if there are
  320. * no more objects to retrieve.
  321. * @throws ConcurrentModificationException if the
  322. * list has been modified elsewhere.
  323. */
  324. public E next()
  325. {
  326. checkMod();
  327. if (pos == size)
  328. throw new NoSuchElementException();
  329. last = pos;
  330. return get(pos++);
  331. }
  332. /**
  333. * Removes the last object retrieved by <code>next()</code>
  334. * from the list, if the list supports object removal.
  335. *
  336. * @throws ConcurrentModificationException if the list
  337. * has been modified elsewhere.
  338. * @throws IllegalStateException if the iterator is positioned
  339. * before the start of the list or the last object has already
  340. * been removed.
  341. * @throws UnsupportedOperationException if the list does
  342. * not support removing elements.
  343. */
  344. public void remove()
  345. {
  346. checkMod();
  347. if (last < 0)
  348. throw new IllegalStateException();
  349. AbstractList.this.remove(last);
  350. pos--;
  351. size--;
  352. last = -1;
  353. knownMod = modCount;
  354. }
  355. };
  356. }
  357. /**
  358. * Obtain the last index at which a given object is to be found in this
  359. * list. This implementation grabs listIterator(size()), then searches
  360. * backwards for a match or returns -1.
  361. *
  362. * @return the greatest integer n such that <code>o == null ? get(n) == null
  363. * : o.equals(get(n))</code>, or -1 if there is no such index
  364. */
  365. public int lastIndexOf(Object o)
  366. {
  367. int pos = size();
  368. ListIterator<E> itr = listIterator(pos);
  369. while (--pos >= 0)
  370. if (equals(o, itr.previous()))
  371. return pos;
  372. return -1;
  373. }
  374. /**
  375. * Obtain a ListIterator over this list, starting at the beginning. This
  376. * implementation returns listIterator(0).
  377. *
  378. * @return a ListIterator over the elements of this list, in order, starting
  379. * at the beginning
  380. */
  381. public ListIterator<E> listIterator()
  382. {
  383. return listIterator(0);
  384. }
  385. /**
  386. * Obtain a ListIterator over this list, starting at a given position.
  387. * A first call to next() would return the same as get(index), and a
  388. * first call to previous() would return the same as get(index - 1).
  389. * <p>
  390. *
  391. * This implementation uses size(), get(int), set(int, Object),
  392. * add(int, Object), and remove(int) of the backing list, and does not
  393. * support remove, set, or add unless the list does. This implementation
  394. * is fail-fast if you correctly maintain modCount.
  395. *
  396. * @param index the position, between 0 and size() inclusive, to begin the
  397. * iteration from
  398. * @return a ListIterator over the elements of this list, in order, starting
  399. * at index
  400. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
  401. * @see #modCount
  402. */
  403. public ListIterator<E> listIterator(final int index)
  404. {
  405. if (index < 0 || index > size())
  406. throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
  407. + size());
  408. return new ListIterator<E>()
  409. {
  410. private int knownMod = modCount;
  411. private int position = index;
  412. private int lastReturned = -1;
  413. private int size = size();
  414. // This will get inlined, since it is private.
  415. /**
  416. * Checks for modifications made to the list from
  417. * elsewhere while iteration is in progress.
  418. *
  419. * @throws ConcurrentModificationException if the
  420. * list has been modified elsewhere.
  421. */
  422. private void checkMod()
  423. {
  424. if (knownMod != modCount)
  425. throw new ConcurrentModificationException();
  426. }
  427. /**
  428. * Tests to see if there are any more objects to
  429. * return.
  430. *
  431. * @return True if the end of the list has not yet been
  432. * reached.
  433. */
  434. public boolean hasNext()
  435. {
  436. return position < size;
  437. }
  438. /**
  439. * Tests to see if there are objects prior to the
  440. * current position in the list.
  441. *
  442. * @return True if objects exist prior to the current
  443. * position of the iterator.
  444. */
  445. public boolean hasPrevious()
  446. {
  447. return position > 0;
  448. }
  449. /**
  450. * Retrieves the next object from the list.
  451. *
  452. * @return The next object.
  453. * @throws NoSuchElementException if there are no
  454. * more objects to retrieve.
  455. * @throws ConcurrentModificationException if the
  456. * list has been modified elsewhere.
  457. */
  458. public E next()
  459. {
  460. checkMod();
  461. if (position == size)
  462. throw new NoSuchElementException();
  463. lastReturned = position;
  464. return get(position++);
  465. }
  466. /**
  467. * Retrieves the previous object from the list.
  468. *
  469. * @return The next object.
  470. * @throws NoSuchElementException if there are no
  471. * previous objects to retrieve.
  472. * @throws ConcurrentModificationException if the
  473. * list has been modified elsewhere.
  474. */
  475. public E previous()
  476. {
  477. checkMod();
  478. if (position == 0)
  479. throw new NoSuchElementException();
  480. lastReturned = --position;
  481. return get(lastReturned);
  482. }
  483. /**
  484. * Returns the index of the next element in the
  485. * list, which will be retrieved by <code>next()</code>
  486. *
  487. * @return The index of the next element.
  488. */
  489. public int nextIndex()
  490. {
  491. return position;
  492. }
  493. /**
  494. * Returns the index of the previous element in the
  495. * list, which will be retrieved by <code>previous()</code>
  496. *
  497. * @return The index of the previous element.
  498. */
  499. public int previousIndex()
  500. {
  501. return position - 1;
  502. }
  503. /**
  504. * Removes the last object retrieved by <code>next()</code>
  505. * or <code>previous()</code> from the list, if the list
  506. * supports object removal.
  507. *
  508. * @throws IllegalStateException if the iterator is positioned
  509. * before the start of the list or the last object has already
  510. * been removed.
  511. * @throws UnsupportedOperationException if the list does
  512. * not support removing elements.
  513. * @throws ConcurrentModificationException if the list
  514. * has been modified elsewhere.
  515. */
  516. public void remove()
  517. {
  518. checkMod();
  519. if (lastReturned < 0)
  520. throw new IllegalStateException();
  521. AbstractList.this.remove(lastReturned);
  522. size--;
  523. position = lastReturned;
  524. lastReturned = -1;
  525. knownMod = modCount;
  526. }
  527. /**
  528. * Replaces the last object retrieved by <code>next()</code>
  529. * or <code>previous</code> with o, if the list supports object
  530. * replacement and an add or remove operation has not already
  531. * been performed.
  532. *
  533. * @throws IllegalStateException if the iterator is positioned
  534. * before the start of the list or the last object has already
  535. * been removed.
  536. * @throws UnsupportedOperationException if the list doesn't support
  537. * the addition or removal of elements.
  538. * @throws ClassCastException if the type of o is not a valid type
  539. * for this list.
  540. * @throws IllegalArgumentException if something else related to o
  541. * prevents its addition.
  542. * @throws ConcurrentModificationException if the list
  543. * has been modified elsewhere.
  544. */
  545. public void set(E o)
  546. {
  547. checkMod();
  548. if (lastReturned < 0)
  549. throw new IllegalStateException();
  550. AbstractList.this.set(lastReturned, o);
  551. }
  552. /**
  553. * Adds the supplied object before the element that would be returned
  554. * by a call to <code>next()</code>, if the list supports addition.
  555. *
  556. * @param o The object to add to the list.
  557. * @throws UnsupportedOperationException if the list doesn't support
  558. * the addition of new elements.
  559. * @throws ClassCastException if the type of o is not a valid type
  560. * for this list.
  561. * @throws IllegalArgumentException if something else related to o
  562. * prevents its addition.
  563. * @throws ConcurrentModificationException if the list
  564. * has been modified elsewhere.
  565. */
  566. public void add(E o)
  567. {
  568. checkMod();
  569. AbstractList.this.add(position++, o);
  570. size++;
  571. lastReturned = -1;
  572. knownMod = modCount;
  573. }
  574. };
  575. }
  576. /**
  577. * Remove the element at a given position in this list (optional operation).
  578. * Shifts all remaining elements to the left to fill the gap. This
  579. * implementation always throws an UnsupportedOperationException.
  580. * If you want fail-fast iterators, be sure to increment modCount when
  581. * overriding this.
  582. *
  583. * @param index the position within the list of the object to remove
  584. * @return the object that was removed
  585. * @throws UnsupportedOperationException if this list does not support the
  586. * remove operation
  587. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
  588. * @see #modCount
  589. */
  590. public E remove(int index)
  591. {
  592. throw new UnsupportedOperationException();
  593. }
  594. /**
  595. * Remove a subsection of the list. This is called by the clear and
  596. * removeRange methods of the class which implements subList, which are
  597. * difficult for subclasses to override directly. Therefore, this method
  598. * should be overridden instead by the more efficient implementation, if one
  599. * exists. Overriding this can reduce quadratic efforts to constant time
  600. * in some cases!
  601. * <p>
  602. *
  603. * This implementation first checks for illegal or out of range arguments. It
  604. * then obtains a ListIterator over the list using listIterator(fromIndex).
  605. * It then calls next() and remove() on this iterator repeatedly, toIndex -
  606. * fromIndex times.
  607. *
  608. * @param fromIndex the index, inclusive, to remove from.
  609. * @param toIndex the index, exclusive, to remove to.
  610. * @throws UnsupportedOperationException if the list does
  611. * not support removing elements.
  612. */
  613. protected void removeRange(int fromIndex, int toIndex)
  614. {
  615. ListIterator<E> itr = listIterator(fromIndex);
  616. for (int index = fromIndex; index < toIndex; index++)
  617. {
  618. itr.next();
  619. itr.remove();
  620. }
  621. }
  622. /**
  623. * Replace an element of this list with another object (optional operation).
  624. * This implementation always throws an UnsupportedOperationException.
  625. *
  626. * @param index the position within this list of the element to be replaced
  627. * @param o the object to replace it with
  628. * @return the object that was replaced
  629. * @throws UnsupportedOperationException if this list does not support the
  630. * set operation
  631. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
  632. * @throws ClassCastException if o cannot be added to this list due to its
  633. * type
  634. * @throws IllegalArgumentException if o cannot be added to this list for
  635. * some other reason
  636. */
  637. public E set(int index, E o)
  638. {
  639. throw new UnsupportedOperationException();
  640. }
  641. /**
  642. * Obtain a List view of a subsection of this list, from fromIndex
  643. * (inclusive) to toIndex (exclusive). If the two indices are equal, the
  644. * sublist is empty. The returned list should be modifiable if and only
  645. * if this list is modifiable. Changes to the returned list should be
  646. * reflected in this list. If this list is structurally modified in
  647. * any way other than through the returned list, the result of any subsequent
  648. * operations on the returned list is undefined.
  649. * <p>
  650. *
  651. * This implementation returns a subclass of AbstractList. It stores, in
  652. * private fields, the offset and size of the sublist, and the expected
  653. * modCount of the backing list. If the backing list implements RandomAccess,
  654. * the sublist will also.
  655. * <p>
  656. *
  657. * The subclass's <code>set(int, Object)</code>, <code>get(int)</code>,
  658. * <code>add(int, Object)</code>, <code>remove(int)</code>,
  659. * <code>addAll(int, Collection)</code> and
  660. * <code>removeRange(int, int)</code> methods all delegate to the
  661. * corresponding methods on the backing abstract list, after
  662. * bounds-checking the index and adjusting for the offset. The
  663. * <code>addAll(Collection c)</code> method merely returns addAll(size, c).
  664. * The <code>listIterator(int)</code> method returns a "wrapper object"
  665. * over a list iterator on the backing list, which is created with the
  666. * corresponding method on the backing list. The <code>iterator()</code>
  667. * method merely returns listIterator(), and the <code>size()</code> method
  668. * merely returns the subclass's size field.
  669. * <p>
  670. *
  671. * All methods first check to see if the actual modCount of the backing
  672. * list is equal to its expected value, and throw a
  673. * ConcurrentModificationException if it is not.
  674. *
  675. * @param fromIndex the index that the returned list should start from
  676. * (inclusive)
  677. * @param toIndex the index that the returned list should go to (exclusive)
  678. * @return a List backed by a subsection of this list
  679. * @throws IndexOutOfBoundsException if fromIndex &lt; 0
  680. * || toIndex &gt; size()
  681. * @throws IllegalArgumentException if fromIndex &gt; toIndex
  682. * @see ConcurrentModificationException
  683. * @see RandomAccess
  684. */
  685. public List<E> subList(int fromIndex, int toIndex)
  686. {
  687. // This follows the specification of AbstractList, but is inconsistent
  688. // with the one in List. Don't you love Sun's inconsistencies?
  689. if (fromIndex > toIndex)
  690. throw new IllegalArgumentException(fromIndex + " > " + toIndex);
  691. if (fromIndex < 0 || toIndex > size())
  692. throw new IndexOutOfBoundsException();
  693. if (this instanceof RandomAccess)
  694. return new RandomAccessSubList<E>(this, fromIndex, toIndex);
  695. return new SubList<E>(this, fromIndex, toIndex);
  696. }
  697. /**
  698. * This class follows the implementation requirements set forth in
  699. * {@link AbstractList#subList(int, int)}. It matches Sun's implementation
  700. * by using a non-public top-level class in the same package.
  701. *
  702. * @author Original author unknown
  703. * @author Eric Blake (ebb9@email.byu.edu)
  704. */
  705. private static class SubList<E> extends AbstractList<E>
  706. {
  707. // Package visible, for use by iterator.
  708. /** The original list. */
  709. final AbstractList<E> backingList;
  710. /** The index of the first element of the sublist. */
  711. final int offset;
  712. /** The size of the sublist. */
  713. int size;
  714. /**
  715. * Construct the sublist.
  716. *
  717. * @param backing the list this comes from
  718. * @param fromIndex the lower bound, inclusive
  719. * @param toIndex the upper bound, exclusive
  720. */
  721. SubList(AbstractList<E> backing, int fromIndex, int toIndex)
  722. {
  723. backingList = backing;
  724. modCount = backing.modCount;
  725. offset = fromIndex;
  726. size = toIndex - fromIndex;
  727. }
  728. /**
  729. * This method checks the two modCount fields to ensure that there has
  730. * not been a concurrent modification, returning if all is okay.
  731. *
  732. * @throws ConcurrentModificationException if the backing list has been
  733. * modified externally to this sublist
  734. */
  735. // This can be inlined. Package visible, for use by iterator.
  736. void checkMod()
  737. {
  738. if (modCount != backingList.modCount)
  739. throw new ConcurrentModificationException();
  740. }
  741. /**
  742. * This method checks that a value is between 0 and size (inclusive). If
  743. * it is not, an exception is thrown.
  744. *
  745. * @param index the value to check
  746. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
  747. */
  748. // This will get inlined, since it is private.
  749. private void checkBoundsInclusive(int index)
  750. {
  751. if (index < 0 || index > size)
  752. throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
  753. + size);
  754. }
  755. /**
  756. * This method checks that a value is between 0 (inclusive) and size
  757. * (exclusive). If it is not, an exception is thrown.
  758. *
  759. * @param index the value to check
  760. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
  761. */
  762. // This will get inlined, since it is private.
  763. private void checkBoundsExclusive(int index)
  764. {
  765. if (index < 0 || index >= size)
  766. throw new IndexOutOfBoundsException("Index: " + index + ", Size:"
  767. + size);
  768. }
  769. /**
  770. * Specified by AbstractList.subList to return the private field size.
  771. *
  772. * @return the sublist size
  773. * @throws ConcurrentModificationException if the backing list has been
  774. * modified externally to this sublist
  775. */
  776. public int size()
  777. {
  778. checkMod();
  779. return size;
  780. }
  781. /**
  782. * Specified by AbstractList.subList to delegate to the backing list.
  783. *
  784. * @param index the location to modify
  785. * @param o the new value
  786. * @return the old value
  787. * @throws ConcurrentModificationException if the backing list has been
  788. * modified externally to this sublist
  789. * @throws UnsupportedOperationException if the backing list does not
  790. * support the set operation
  791. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
  792. * @throws ClassCastException if o cannot be added to the backing list due
  793. * to its type
  794. * @throws IllegalArgumentException if o cannot be added to the backing list
  795. * for some other reason
  796. */
  797. public E set(int index, E o)
  798. {
  799. checkMod();
  800. checkBoundsExclusive(index);
  801. return backingList.set(index + offset, o);
  802. }
  803. /**
  804. * Specified by AbstractList.subList to delegate to the backing list.
  805. *
  806. * @param index the location to get from
  807. * @return the object at that location
  808. * @throws ConcurrentModificationException if the backing list has been
  809. * modified externally to this sublist
  810. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
  811. */
  812. public E get(int index)
  813. {
  814. checkMod();
  815. checkBoundsExclusive(index);
  816. return backingList.get(index + offset);
  817. }
  818. /**
  819. * Specified by AbstractList.subList to delegate to the backing list.
  820. *
  821. * @param index the index to insert at
  822. * @param o the object to add
  823. * @throws ConcurrentModificationException if the backing list has been
  824. * modified externally to this sublist
  825. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
  826. * @throws UnsupportedOperationException if the backing list does not
  827. * support the add operation.
  828. * @throws ClassCastException if o cannot be added to the backing list due
  829. * to its type.
  830. * @throws IllegalArgumentException if o cannot be added to the backing
  831. * list for some other reason.
  832. */
  833. public void add(int index, E o)
  834. {
  835. checkMod();
  836. checkBoundsInclusive(index);
  837. backingList.add(index + offset, o);
  838. size++;
  839. modCount = backingList.modCount;
  840. }
  841. /**
  842. * Specified by AbstractList.subList to delegate to the backing list.
  843. *
  844. * @param index the index to remove
  845. * @return the removed object
  846. * @throws ConcurrentModificationException if the backing list has been
  847. * modified externally to this sublist
  848. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt;= size()
  849. * @throws UnsupportedOperationException if the backing list does not
  850. * support the remove operation
  851. */
  852. public E remove(int index)
  853. {
  854. checkMod();
  855. checkBoundsExclusive(index);
  856. E o = backingList.remove(index + offset);
  857. size--;
  858. modCount = backingList.modCount;
  859. return o;
  860. }
  861. /**
  862. * Specified by AbstractList.subList to delegate to the backing list.
  863. * This does no bounds checking, as it assumes it will only be called
  864. * by trusted code like clear() which has already checked the bounds.
  865. *
  866. * @param fromIndex the lower bound, inclusive
  867. * @param toIndex the upper bound, exclusive
  868. * @throws ConcurrentModificationException if the backing list has been
  869. * modified externally to this sublist
  870. * @throws UnsupportedOperationException if the backing list does
  871. * not support removing elements.
  872. */
  873. protected void removeRange(int fromIndex, int toIndex)
  874. {
  875. checkMod();
  876. backingList.removeRange(offset + fromIndex, offset + toIndex);
  877. size -= toIndex - fromIndex;
  878. modCount = backingList.modCount;
  879. }
  880. /**
  881. * Specified by AbstractList.subList to delegate to the backing list.
  882. *
  883. * @param index the location to insert at
  884. * @param c the collection to insert
  885. * @return true if this list was modified, in other words, c is non-empty
  886. * @throws ConcurrentModificationException if the backing list has been
  887. * modified externally to this sublist
  888. * @throws IndexOutOfBoundsException if index &lt; 0 || index &gt; size()
  889. * @throws UnsupportedOperationException if this list does not support the
  890. * addAll operation
  891. * @throws ClassCastException if some element of c cannot be added to this
  892. * list due to its type
  893. * @throws IllegalArgumentException if some element of c cannot be added
  894. * to this list for some other reason
  895. * @throws NullPointerException if the specified collection is null
  896. */
  897. public boolean addAll(int index, Collection<? extends E> c)
  898. {
  899. checkMod();
  900. checkBoundsInclusive(index);
  901. int csize = c.size();
  902. boolean result = backingList.addAll(offset + index, c);
  903. size += csize;
  904. modCount = backingList.modCount;
  905. return result;
  906. }
  907. /**
  908. * Specified by AbstractList.subList to return addAll(size, c).
  909. *
  910. * @param c the collection to insert
  911. * @return true if this list was modified, in other words, c is non-empty
  912. * @throws ConcurrentModificationException if the backing list has been
  913. * modified externally to this sublist
  914. * @throws UnsupportedOperationException if this list does not support the
  915. * addAll operation
  916. * @throws ClassCastException if some element of c cannot be added to this
  917. * list due to its type
  918. * @throws IllegalArgumentException if some element of c cannot be added
  919. * to this list for some other reason
  920. * @throws NullPointerException if the specified collection is null
  921. */
  922. public boolean addAll(Collection<? extends E> c)
  923. {
  924. return addAll(size, c);
  925. }
  926. /**
  927. * Specified by AbstractList.subList to return listIterator().
  928. *
  929. * @return an iterator over the sublist
  930. */
  931. public Iterator<E> iterator()
  932. {
  933. return listIterator();
  934. }
  935. /**
  936. * Specified by AbstractList.subList to return a wrapper around the
  937. * backing list's iterator.
  938. *
  939. * @param index the start location of the iterator
  940. * @return a list iterator over the sublist
  941. * @throws ConcurrentModificationException if the backing list has been
  942. * modified externally to this sublist
  943. * @throws IndexOutOfBoundsException if the value is out of range
  944. */
  945. public ListIterator<E> listIterator(final int index)
  946. {
  947. checkMod();
  948. checkBoundsInclusive(index);
  949. return new ListIterator<E>()
  950. {
  951. private final ListIterator<E> i
  952. = backingList.listIterator(index + offset);
  953. private int position = index;
  954. /**
  955. * Tests to see if there are any more objects to
  956. * return.
  957. *
  958. * @return True if the end of the list has not yet been
  959. * reached.
  960. */
  961. public boolean hasNext()
  962. {
  963. return position < size;
  964. }
  965. /**
  966. * Tests to see if there are objects prior to the
  967. * current position in the list.
  968. *
  969. * @return True if objects exist prior to the current
  970. * position of the iterator.
  971. */
  972. public boolean hasPrevious()
  973. {
  974. return position > 0;
  975. }
  976. /**
  977. * Retrieves the next object from the list.
  978. *
  979. * @return The next object.
  980. * @throws NoSuchElementException if there are no
  981. * more objects to retrieve.
  982. * @throws ConcurrentModificationException if the
  983. * list has been modified elsewhere.
  984. */
  985. public E next()
  986. {
  987. if (position == size)
  988. throw new NoSuchElementException();
  989. position++;
  990. return i.next();
  991. }
  992. /**
  993. * Retrieves the previous object from the list.
  994. *
  995. * @return The next object.
  996. * @throws NoSuchElementException if there are no
  997. * previous objects to retrieve.
  998. * @throws ConcurrentModificationException if the
  999. * list has been modified elsewhere.
  1000. */
  1001. public E previous()
  1002. {
  1003. if (position == 0)
  1004. throw new NoSuchElementException();
  1005. position--;
  1006. return i.previous();
  1007. }
  1008. /**
  1009. * Returns the index of the next element in the
  1010. * list, which will be retrieved by <code>next()</code>
  1011. *
  1012. * @return The index of the next element.
  1013. */
  1014. public int nextIndex()
  1015. {
  1016. return i.nextIndex() - offset;
  1017. }
  1018. /**
  1019. * Returns the index of the previous element in the
  1020. * list, which will be retrieved by <code>previous()</code>
  1021. *
  1022. * @return The index of the previous element.
  1023. */
  1024. public int previousIndex()
  1025. {
  1026. return i.previousIndex() - offset;
  1027. }
  1028. /**
  1029. * Removes the last object retrieved by <code>next()</code>
  1030. * from the list, if the list supports object removal.
  1031. *
  1032. * @throws IllegalStateException if the iterator is positioned
  1033. * before the start of the list or the last object has already
  1034. * been removed.
  1035. * @throws UnsupportedOperationException if the list does
  1036. * not support removing elements.
  1037. */
  1038. public void remove()
  1039. {
  1040. i.remove();
  1041. size--;
  1042. position = nextIndex();
  1043. modCount = backingList.modCount;
  1044. }
  1045. /**
  1046. * Replaces the last object retrieved by <code>next()</code>
  1047. * or <code>previous</code> with o, if the list supports object
  1048. * replacement and an add or remove operation has not already
  1049. * been performed.
  1050. *
  1051. * @throws IllegalStateException if the iterator is positioned
  1052. * before the start of the list or the last object has already
  1053. * been removed.
  1054. * @throws UnsupportedOperationException if the list doesn't support
  1055. * the addition or removal of elements.
  1056. * @throws ClassCastException if the type of o is not a valid type
  1057. * for this list.
  1058. * @throws IllegalArgumentException if something else related to o
  1059. * prevents its addition.
  1060. * @throws ConcurrentModificationException if the list
  1061. * has been modified elsewhere.
  1062. */
  1063. public void set(E o)
  1064. {
  1065. i.set(o);
  1066. }
  1067. /**
  1068. * Adds the supplied object before the element that would be returned
  1069. * by a call to <code>next()</code>, if the list supports addition.
  1070. *
  1071. * @param o The object to add to the list.
  1072. * @throws UnsupportedOperationException if the list doesn't support
  1073. * the addition of new elements.
  1074. * @throws ClassCastException if the type of o is not a valid type
  1075. * for this list.
  1076. * @throws IllegalArgumentException if something else related to o
  1077. * prevents its addition.
  1078. * @throws ConcurrentModificationException if the list
  1079. * has been modified elsewhere.
  1080. */
  1081. public void add(E o)
  1082. {
  1083. i.add(o);
  1084. size++;
  1085. position++;
  1086. modCount = backingList.modCount;
  1087. }
  1088. // Here is the reason why the various modCount fields are mostly
  1089. // ignored in this wrapper listIterator.
  1090. // If the backing listIterator is failfast, then the following holds:
  1091. // Using any other method on this list will call a corresponding
  1092. // method on the backing list *after* the backing listIterator
  1093. // is created, which will in turn cause a ConcurrentModException
  1094. // when this listIterator comes to use the backing one. So it is
  1095. // implicitly failfast.
  1096. // If the backing listIterator is NOT failfast, then the whole of
  1097. // this list isn't failfast, because the modCount field of the
  1098. // backing list is not valid. It would still be *possible* to
  1099. // make the iterator failfast wrt modifications of the sublist
  1100. // only, but somewhat pointless when the list can be changed under
  1101. // us.
  1102. // Either way, no explicit handling of modCount is needed.
  1103. // However modCount = backingList.modCount must be executed in add
  1104. // and remove, and size must also be updated in these two methods,
  1105. // since they do not go through the corresponding methods of the subList.
  1106. };
  1107. }
  1108. } // class SubList
  1109. /**
  1110. * This class is a RandomAccess version of SubList, as required by
  1111. * {@link AbstractList#subList(int, int)}.
  1112. *
  1113. * @author Eric Blake (ebb9@email.byu.edu)
  1114. */
  1115. private static final class RandomAccessSubList<E> extends SubList<E>
  1116. implements RandomAccess
  1117. {
  1118. /**
  1119. * Construct the sublist.
  1120. *
  1121. * @param backing the list this comes from
  1122. * @param fromIndex the lower bound, inclusive
  1123. * @param toIndex the upper bound, exclusive
  1124. */
  1125. RandomAccessSubList(AbstractList<E> backing, int fromIndex, int toIndex)
  1126. {
  1127. super(backing, fromIndex, toIndex);
  1128. }
  1129. } // class RandomAccessSubList
  1130. } // class AbstractList