e61304584727dd775e9470a8b0a5ba435b21a6bb.svn-base 38 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088
  1. package com.sinosoft.cm.common;
  2. import java.util.Arrays;
  3. import java.util.Collection;
  4. import java.util.Collections;
  5. import java.util.ConcurrentModificationException;
  6. import java.util.Iterator;
  7. import java.util.List;
  8. import java.util.ListIterator;
  9. import java.util.NoSuchElementException;
  10. import java.util.RandomAccess;
  11. public class ArrayList<E> extends AbstractList<E>
  12. implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  13. {
  14. private static final long serialVersionUID = 8683452581122892189L;
  15. /**
  16. * Default initial capacity.
  17. */
  18. private static final int DEFAULT_CAPACITY = 10;
  19. /**
  20. * Shared empty array instance used for empty instances.
  21. */
  22. private static final Object[] EMPTY_ELEMENTDATA = {};
  23. /**
  24. * The array buffer into which the elements of the ArrayList are stored.
  25. * The capacity of the ArrayList is the length of this array buffer. Any
  26. * empty ArrayList with elementData == EMPTY_ELEMENTDATA will be expanded to
  27. * DEFAULT_CAPACITY when the first element is added.
  28. */
  29. private transient Object[] elementData;
  30. /**
  31. * The size of the ArrayList (the number of elements it contains).
  32. *
  33. * @serial
  34. */
  35. private int size;
  36. /**
  37. * Constructs an empty list with the specified initial capacity.
  38. *
  39. * @param initialCapacity the initial capacity of the list
  40. * @throws IllegalArgumentException if the specified initial capacity
  41. * is negative
  42. */
  43. public ArrayList(int initialCapacity) {
  44. super();
  45. if (initialCapacity < 0)
  46. throw new IllegalArgumentException("Illegal Capacity: "+
  47. initialCapacity);
  48. this.elementData = new Object[initialCapacity];
  49. }
  50. /**
  51. * Constructs an empty list with an initial capacity of ten.
  52. */
  53. public ArrayList() {
  54. super();
  55. this.elementData = EMPTY_ELEMENTDATA;
  56. }
  57. /**
  58. * Constructs a list containing the elements of the specified
  59. * collection, in the order they are returned by the collection's
  60. * iterator.
  61. *
  62. * @param c the collection whose elements are to be placed into this list
  63. * @throws NullPointerException if the specified collection is null
  64. */
  65. public ArrayList(Collection<? extends E> c) {
  66. elementData = c.toArray();
  67. size = elementData.length;
  68. // c.toArray might (incorrectly) not return Object[] (see 6260652)
  69. if (elementData.getClass() != Object[].class)
  70. elementData = Arrays.copyOf(elementData, size, Object[].class);
  71. }
  72. /**
  73. * Trims the capacity of this <tt>ArrayList</tt> instance to be the
  74. * list's current size. An application can use this operation to minimize
  75. * the storage of an <tt>ArrayList</tt> instance.
  76. */
  77. public void trimToSize() {
  78. modCount++;
  79. if (size < elementData.length) {
  80. elementData = Arrays.copyOf(elementData, size);
  81. }
  82. }
  83. /**
  84. * Increases the capacity of this <tt>ArrayList</tt> instance, if
  85. * necessary, to ensure that it can hold at least the number of elements
  86. * specified by the minimum capacity argument.
  87. *
  88. * @param minCapacity the desired minimum capacity
  89. */
  90. public void ensureCapacity(int minCapacity) {
  91. int minExpand = (elementData != EMPTY_ELEMENTDATA)
  92. // any size if real element table
  93. ? 0
  94. // larger than default for empty table. It's already supposed to be
  95. // at default size.
  96. : DEFAULT_CAPACITY;
  97. if (minCapacity > minExpand) {
  98. ensureExplicitCapacity(minCapacity);
  99. }
  100. }
  101. private void ensureCapacityInternal(int minCapacity) {
  102. if (elementData == EMPTY_ELEMENTDATA) {
  103. minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
  104. }
  105. ensureExplicitCapacity(minCapacity);
  106. }
  107. private void ensureExplicitCapacity(int minCapacity) {
  108. modCount++;
  109. // overflow-conscious code
  110. if (minCapacity - elementData.length > 0)
  111. grow(minCapacity);
  112. }
  113. /**
  114. * The maximum size of array to allocate.
  115. * Some VMs reserve some header words in an array.
  116. * Attempts to allocate larger arrays may result in
  117. * OutOfMemoryError: Requested array size exceeds VM limit
  118. */
  119. private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
  120. /**
  121. * Increases the capacity to ensure that it can hold at least the
  122. * number of elements specified by the minimum capacity argument.
  123. *
  124. * @param minCapacity the desired minimum capacity
  125. */
  126. private void grow(int minCapacity) {
  127. // overflow-conscious code
  128. int oldCapacity = elementData.length;
  129. int newCapacity = oldCapacity + (oldCapacity >> 1);
  130. if (newCapacity - minCapacity < 0)
  131. newCapacity = minCapacity;
  132. if (newCapacity - MAX_ARRAY_SIZE > 0)
  133. newCapacity = hugeCapacity(minCapacity);
  134. // minCapacity is usually close to size, so this is a win:
  135. elementData = Arrays.copyOf(elementData, newCapacity);
  136. }
  137. private static int hugeCapacity(int minCapacity) {
  138. if (minCapacity < 0) // overflow
  139. throw new OutOfMemoryError();
  140. return (minCapacity > MAX_ARRAY_SIZE) ?
  141. Integer.MAX_VALUE :
  142. MAX_ARRAY_SIZE;
  143. }
  144. /**
  145. * Returns the number of elements in this list.
  146. *
  147. * @return the number of elements in this list
  148. */
  149. public int size() {
  150. return size;
  151. }
  152. /**
  153. * Returns <tt>true</tt> if this list contains no elements.
  154. *
  155. * @return <tt>true</tt> if this list contains no elements
  156. */
  157. public boolean isEmpty() {
  158. return size == 0;
  159. }
  160. /**
  161. * Returns <tt>true</tt> if this list contains the specified element.
  162. * More formally, returns <tt>true</tt> if and only if this list contains
  163. * at least one element <tt>e</tt> such that
  164. * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
  165. *
  166. * @param o element whose presence in this list is to be tested
  167. * @return <tt>true</tt> if this list contains the specified element
  168. */
  169. public boolean contains(Object o) {
  170. return indexOf(o) >= 0;
  171. }
  172. /**
  173. * Returns the index of the first occurrence of the specified element
  174. * in this list, or -1 if this list does not contain the element.
  175. * More formally, returns the lowest index <tt>i</tt> such that
  176. * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  177. * or -1 if there is no such index.
  178. */
  179. public int indexOf(Object o) {
  180. if (o == null) {
  181. for (int i = 0; i < size; i++)
  182. if (elementData[i]==null)
  183. return i;
  184. } else {
  185. for (int i = 0; i < size; i++)
  186. if (o.equals(elementData[i]))
  187. return i;
  188. }
  189. return -1;
  190. }
  191. /**
  192. * Returns the index of the last occurrence of the specified element
  193. * in this list, or -1 if this list does not contain the element.
  194. * More formally, returns the highest index <tt>i</tt> such that
  195. * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>,
  196. * or -1 if there is no such index.
  197. */
  198. public int lastIndexOf(Object o) {
  199. if (o == null) {
  200. for (int i = size-1; i >= 0; i--)
  201. if (elementData[i]==null)
  202. return i;
  203. } else {
  204. for (int i = size-1; i >= 0; i--)
  205. if (o.equals(elementData[i]))
  206. return i;
  207. }
  208. return -1;
  209. }
  210. /**
  211. * Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
  212. * elements themselves are not copied.)
  213. *
  214. * @return a clone of this <tt>ArrayList</tt> instance
  215. */
  216. public Object clone() {
  217. try {
  218. @SuppressWarnings("unchecked")
  219. ArrayList<E> v = (ArrayList<E>) super.clone();
  220. v.elementData = Arrays.copyOf(elementData, size);
  221. v.modCount = 0;
  222. return v;
  223. } catch (CloneNotSupportedException e) {
  224. // this shouldn't happen, since we are Cloneable
  225. throw new InternalError();
  226. }
  227. }
  228. /**
  229. * Returns an array containing all of the elements in this list
  230. * in proper sequence (from first to last element).
  231. *
  232. * <p>The returned array will be "safe" in that no references to it are
  233. * maintained by this list. (In other words, this method must allocate
  234. * a new array). The caller is thus free to modify the returned array.
  235. *
  236. * <p>This method acts as bridge between array-based and collection-based
  237. * APIs.
  238. *
  239. * @return an array containing all of the elements in this list in
  240. * proper sequence
  241. */
  242. public Object[] toArray() {
  243. return Arrays.copyOf(elementData, size);
  244. }
  245. /**
  246. * Returns an array containing all of the elements in this list in proper
  247. * sequence (from first to last element); the runtime type of the returned
  248. * array is that of the specified array. If the list fits in the
  249. * specified array, it is returned therein. Otherwise, a new array is
  250. * allocated with the runtime type of the specified array and the size of
  251. * this list.
  252. *
  253. * <p>If the list fits in the specified array with room to spare
  254. * (i.e., the array has more elements than the list), the element in
  255. * the array immediately following the end of the collection is set to
  256. * <tt>null</tt>. (This is useful in determining the length of the
  257. * list <i>only</i> if the caller knows that the list does not contain
  258. * any null elements.)
  259. *
  260. * @param a the array into which the elements of the list are to
  261. * be stored, if it is big enough; otherwise, a new array of the
  262. * same runtime type is allocated for this purpose.
  263. * @return an array containing the elements of the list
  264. * @throws ArrayStoreException if the runtime type of the specified array
  265. * is not a supertype of the runtime type of every element in
  266. * this list
  267. * @throws NullPointerException if the specified array is null
  268. */
  269. @SuppressWarnings("unchecked")
  270. public <T> T[] toArray(T[] a) {
  271. if (a.length < size)
  272. // Make a new array of a's runtime type, but my contents:
  273. return (T[]) Arrays.copyOf(elementData, size, a.getClass());
  274. System.arraycopy(elementData, 0, a, 0, size);
  275. if (a.length > size)
  276. a[size] = null;
  277. return a;
  278. }
  279. // Positional Access Operations
  280. @SuppressWarnings("unchecked")
  281. E elementData(int index) {
  282. return (E) elementData[index];
  283. }
  284. /**
  285. * Returns the element at the specified position in this list.
  286. *
  287. * @param index index of the element to return
  288. * @return the element at the specified position in this list
  289. * @throws IndexOutOfBoundsException {@inheritDoc}
  290. */
  291. public E get(int index) {
  292. rangeCheck(index);
  293. return elementData(index);
  294. }
  295. /**
  296. * Replaces the element at the specified position in this list with
  297. * the specified element.
  298. *
  299. * @param index index of the element to replace
  300. * @param element element to be stored at the specified position
  301. * @return the element previously at the specified position
  302. * @throws IndexOutOfBoundsException {@inheritDoc}
  303. */
  304. public E set(int index, E element) {
  305. rangeCheck(index);
  306. E oldValue = elementData(index);
  307. elementData[index] = element;
  308. return oldValue;
  309. }
  310. /**
  311. * Appends the specified element to the end of this list.
  312. *
  313. * @param e element to be appended to this list
  314. * @return <tt>true</tt> (as specified by {@link Collection#add})
  315. */
  316. public boolean add(E e) {
  317. ensureCapacityInternal(size + 1); // Increments modCount!!
  318. elementData[size++] = e;
  319. return true;
  320. }
  321. /**
  322. * Inserts the specified element at the specified position in this
  323. * list. Shifts the element currently at that position (if any) and
  324. * any subsequent elements to the right (adds one to their indices).
  325. *
  326. * @param index index at which the specified element is to be inserted
  327. * @param element element to be inserted
  328. * @throws IndexOutOfBoundsException {@inheritDoc}
  329. */
  330. public void add(int index, E element) {
  331. rangeCheckForAdd(index);
  332. ensureCapacityInternal(size + 1); // Increments modCount!!
  333. System.arraycopy(elementData, index, elementData, index + 1,
  334. size - index);
  335. elementData[index] = element;
  336. size++;
  337. }
  338. /**
  339. * Removes the element at the specified position in this list.
  340. * Shifts any subsequent elements to the left (subtracts one from their
  341. * indices).
  342. *
  343. * @param index the index of the element to be removed
  344. * @return the element that was removed from the list
  345. * @throws IndexOutOfBoundsException {@inheritDoc}
  346. */
  347. public E remove(int index) {
  348. rangeCheck(index);
  349. modCount++;
  350. E oldValue = elementData(index);
  351. int numMoved = size - index - 1;
  352. if (numMoved > 0)
  353. System.arraycopy(elementData, index+1, elementData, index,
  354. numMoved);
  355. elementData[--size] = null; // clear to let GC do its work
  356. return oldValue;
  357. }
  358. /**
  359. * Removes the first occurrence of the specified element from this list,
  360. * if it is present. If the list does not contain the element, it is
  361. * unchanged. More formally, removes the element with the lowest index
  362. * <tt>i</tt> such that
  363. * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
  364. * (if such an element exists). Returns <tt>true</tt> if this list
  365. * contained the specified element (or equivalently, if this list
  366. * changed as a result of the call).
  367. *
  368. * @param o element to be removed from this list, if present
  369. * @return <tt>true</tt> if this list contained the specified element
  370. */
  371. public boolean remove(Object o) {
  372. if (o == null) {
  373. for (int index = 0; index < size; index++)
  374. if (elementData[index] == null) {
  375. fastRemove(index);
  376. return true;
  377. }
  378. } else {
  379. for (int index = 0; index < size; index++)
  380. if (o.equals(elementData[index])) {
  381. fastRemove(index);
  382. return true;
  383. }
  384. }
  385. return false;
  386. }
  387. /*
  388. * Private remove method that skips bounds checking and does not
  389. * return the value removed.
  390. */
  391. private void fastRemove(int index) {
  392. modCount++;
  393. int numMoved = size - index - 1;
  394. if (numMoved > 0)
  395. System.arraycopy(elementData, index+1, elementData, index,
  396. numMoved);
  397. elementData[--size] = null; // clear to let GC do its work
  398. }
  399. /**
  400. * Removes all of the elements from this list. The list will
  401. * be empty after this call returns.
  402. */
  403. public void clear() {
  404. modCount++;
  405. // clear to let GC do its work
  406. for (int i = 0; i < size; i++)
  407. elementData[i] = null;
  408. size = 0;
  409. }
  410. /**
  411. * Appends all of the elements in the specified collection to the end of
  412. * this list, in the order that they are returned by the
  413. * specified collection's Iterator. The behavior of this operation is
  414. * undefined if the specified collection is modified while the operation
  415. * is in progress. (This implies that the behavior of this call is
  416. * undefined if the specified collection is this list, and this
  417. * list is nonempty.)
  418. *
  419. * @param c collection containing elements to be added to this list
  420. * @return <tt>true</tt> if this list changed as a result of the call
  421. * @throws NullPointerException if the specified collection is null
  422. */
  423. public boolean addAll(Collection<? extends E> c) {
  424. Object[] a = c.toArray();
  425. int numNew = a.length;
  426. ensureCapacityInternal(size + numNew); // Increments modCount
  427. System.arraycopy(a, 0, elementData, size, numNew);
  428. size += numNew;
  429. return numNew != 0;
  430. }
  431. /**
  432. * Inserts all of the elements in the specified collection into this
  433. * list, starting at the specified position. Shifts the element
  434. * currently at that position (if any) and any subsequent elements to
  435. * the right (increases their indices). The new elements will appear
  436. * in the list in the order that they are returned by the
  437. * specified collection's iterator.
  438. *
  439. * @param index index at which to insert the first element from the
  440. * specified collection
  441. * @param c collection containing elements to be added to this list
  442. * @return <tt>true</tt> if this list changed as a result of the call
  443. * @throws IndexOutOfBoundsException {@inheritDoc}
  444. * @throws NullPointerException if the specified collection is null
  445. */
  446. public boolean addAll(int index, Collection<? extends E> c) {
  447. rangeCheckForAdd(index);
  448. Object[] a = c.toArray();
  449. int numNew = a.length;
  450. ensureCapacityInternal(size + numNew); // Increments modCount
  451. int numMoved = size - index;
  452. if (numMoved > 0)
  453. System.arraycopy(elementData, index, elementData, index + numNew,
  454. numMoved);
  455. System.arraycopy(a, 0, elementData, index, numNew);
  456. size += numNew;
  457. return numNew != 0;
  458. }
  459. /**
  460. * Removes from this list all of the elements whose index is between
  461. * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
  462. * Shifts any succeeding elements to the left (reduces their index).
  463. * This call shortens the list by {@code (toIndex - fromIndex)} elements.
  464. * (If {@code toIndex==fromIndex}, this operation has no effect.)
  465. *
  466. * @throws IndexOutOfBoundsException if {@code fromIndex} or
  467. * {@code toIndex} is out of range
  468. * ({@code fromIndex < 0 ||
  469. * fromIndex >= size() ||
  470. * toIndex > size() ||
  471. * toIndex < fromIndex})
  472. */
  473. protected void removeRange(int fromIndex, int toIndex) {
  474. modCount++;
  475. int numMoved = size - toIndex;
  476. System.arraycopy(elementData, toIndex, elementData, fromIndex,
  477. numMoved);
  478. // clear to let GC do its work
  479. int newSize = size - (toIndex-fromIndex);
  480. for (int i = newSize; i < size; i++) {
  481. elementData[i] = null;
  482. }
  483. size = newSize;
  484. }
  485. /**
  486. * Checks if the given index is in range. If not, throws an appropriate
  487. * runtime exception. This method does *not* check if the index is
  488. * negative: It is always used immediately prior to an array access,
  489. * which throws an ArrayIndexOutOfBoundsException if index is negative.
  490. */
  491. private void rangeCheck(int index) {
  492. if (index >= size)
  493. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  494. }
  495. /**
  496. * A version of rangeCheck used by add and addAll.
  497. */
  498. private void rangeCheckForAdd(int index) {
  499. if (index > size || index < 0)
  500. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  501. }
  502. /**
  503. * Constructs an IndexOutOfBoundsException detail message.
  504. * Of the many possible refactorings of the error handling code,
  505. * this "outlining" performs best with both server and client VMs.
  506. */
  507. private String outOfBoundsMsg(int index) {
  508. return "Index: "+index+", Size: "+size;
  509. }
  510. /**
  511. * Removes from this list all of its elements that are contained in the
  512. * specified collection.
  513. *
  514. * @param c collection containing elements to be removed from this list
  515. * @return {@code true} if this list changed as a result of the call
  516. * @throws ClassCastException if the class of an element of this list
  517. * is incompatible with the specified collection
  518. * (<a href="Collection.html#optional-restrictions">optional</a>)
  519. * @throws NullPointerException if this list contains a null element and the
  520. * specified collection does not permit null elements
  521. * (<a href="Collection.html#optional-restrictions">optional</a>),
  522. * or if the specified collection is null
  523. * @see Collection#contains(Object)
  524. */
  525. public boolean removeAll(Collection<?> c) {
  526. return batchRemove(c, false);
  527. }
  528. /**
  529. * Retains only the elements in this list that are contained in the
  530. * specified collection. In other words, removes from this list all
  531. * of its elements that are not contained in the specified collection.
  532. *
  533. * @param c collection containing elements to be retained in this list
  534. * @return {@code true} if this list changed as a result of the call
  535. * @throws ClassCastException if the class of an element of this list
  536. * is incompatible with the specified collection
  537. * (<a href="Collection.html#optional-restrictions">optional</a>)
  538. * @throws NullPointerException if this list contains a null element and the
  539. * specified collection does not permit null elements
  540. * (<a href="Collection.html#optional-restrictions">optional</a>),
  541. * or if the specified collection is null
  542. * @see Collection#contains(Object)
  543. */
  544. public boolean retainAll(Collection<?> c) {
  545. return batchRemove(c, true);
  546. }
  547. private boolean batchRemove(Collection<?> c, boolean complement) {
  548. final Object[] elementData = this.elementData;
  549. int r = 0, w = 0;
  550. boolean modified = false;
  551. try {
  552. for (; r < size; r++)
  553. if (c.contains(elementData[r]) == complement)
  554. elementData[w++] = elementData[r];
  555. } finally {
  556. // Preserve behavioral compatibility with AbstractCollection,
  557. // even if c.contains() throws.
  558. if (r != size) {
  559. System.arraycopy(elementData, r,
  560. elementData, w,
  561. size - r);
  562. w += size - r;
  563. }
  564. if (w != size) {
  565. // clear to let GC do its work
  566. for (int i = w; i < size; i++)
  567. elementData[i] = null;
  568. modCount += size - w;
  569. size = w;
  570. modified = true;
  571. }
  572. }
  573. return modified;
  574. }
  575. /**
  576. * Save the state of the <tt>ArrayList</tt> instance to a stream (that
  577. * is, serialize it).
  578. *
  579. * @serialData The length of the array backing the <tt>ArrayList</tt>
  580. * instance is emitted (int), followed by all of its elements
  581. * (each an <tt>Object</tt>) in the proper order.
  582. */
  583. private void writeObject(java.io.ObjectOutputStream s)
  584. throws java.io.IOException{
  585. // Write out element count, and any hidden stuff
  586. int expectedModCount = modCount;
  587. s.defaultWriteObject();
  588. // Write out size as capacity for behavioural compatibility with clone()
  589. s.writeInt(size);
  590. // Write out all elements in the proper order.
  591. for (int i=0; i<size; i++) {
  592. s.writeObject(elementData[i]);
  593. }
  594. if (modCount != expectedModCount) {
  595. throw new ConcurrentModificationException();
  596. }
  597. }
  598. /**
  599. * Reconstitute the <tt>ArrayList</tt> instance from a stream (that is,
  600. * deserialize it).
  601. */
  602. private void readObject(java.io.ObjectInputStream s)
  603. throws java.io.IOException, ClassNotFoundException {
  604. elementData = EMPTY_ELEMENTDATA;
  605. // Read in size, and any hidden stuff
  606. s.defaultReadObject();
  607. // Read in capacity
  608. s.readInt(); // ignored
  609. if (size > 0) {
  610. // be like clone(), allocate array based upon size not capacity
  611. ensureCapacityInternal(size);
  612. Object[] a = elementData;
  613. // Read in all elements in the proper order.
  614. for (int i=0; i<size; i++) {
  615. a[i] = s.readObject();
  616. }
  617. }
  618. }
  619. /**
  620. * Returns a list iterator over the elements in this list (in proper
  621. * sequence), starting at the specified position in the list.
  622. * The specified index indicates the first element that would be
  623. * returned by an initial call to {@link ListIterator#next next}.
  624. * An initial call to {@link ListIterator#previous previous} would
  625. * return the element with the specified index minus one.
  626. *
  627. * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
  628. *
  629. * @throws IndexOutOfBoundsException {@inheritDoc}
  630. */
  631. public ListIterator<E> listIterator(int index) {
  632. if (index < 0 || index > size)
  633. throw new IndexOutOfBoundsException("Index: "+index);
  634. return new ListItr(index);
  635. }
  636. /**
  637. * Returns a list iterator over the elements in this list (in proper
  638. * sequence).
  639. *
  640. * <p>The returned list iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
  641. *
  642. * @see #listIterator(int)
  643. */
  644. public ListIterator<E> listIterator() {
  645. return new ListItr(0);
  646. }
  647. /**
  648. * Returns an iterator over the elements in this list in proper sequence.
  649. *
  650. * <p>The returned iterator is <a href="#fail-fast"><i>fail-fast</i></a>.
  651. *
  652. * @return an iterator over the elements in this list in proper sequence
  653. */
  654. public Iterator<E> iterator() {
  655. return new Itr();
  656. }
  657. /**
  658. * An optimized version of AbstractList.Itr
  659. */
  660. private class Itr implements Iterator<E> {
  661. int cursor; // index of next element to return
  662. int lastRet = -1; // index of last element returned; -1 if no such
  663. int expectedModCount = modCount;
  664. public boolean hasNext() {
  665. return cursor != size;
  666. }
  667. @SuppressWarnings("unchecked")
  668. public E next() {
  669. checkForComodification();
  670. int i = cursor;
  671. if (i >= size)
  672. throw new NoSuchElementException();
  673. Object[] elementData = ArrayList.this.elementData;
  674. if (i >= elementData.length)
  675. throw new ConcurrentModificationException();
  676. cursor = i + 1;
  677. return (E) elementData[lastRet = i];
  678. }
  679. public void remove() {
  680. if (lastRet < 0)
  681. throw new IllegalStateException();
  682. checkForComodification();
  683. try {
  684. ArrayList.this.remove(lastRet);
  685. cursor = lastRet;
  686. lastRet = -1;
  687. expectedModCount = modCount;
  688. } catch (IndexOutOfBoundsException ex) {
  689. throw new ConcurrentModificationException();
  690. }
  691. }
  692. final void checkForComodification() {
  693. if (modCount != expectedModCount)
  694. throw new ConcurrentModificationException();
  695. }
  696. }
  697. /**
  698. * An optimized version of AbstractList.ListItr
  699. */
  700. private class ListItr extends Itr implements ListIterator<E> {
  701. ListItr(int index) {
  702. super();
  703. cursor = index;
  704. }
  705. public boolean hasPrevious() {
  706. return cursor != 0;
  707. }
  708. public int nextIndex() {
  709. return cursor;
  710. }
  711. public int previousIndex() {
  712. return cursor - 1;
  713. }
  714. @SuppressWarnings("unchecked")
  715. public E previous() {
  716. checkForComodification();
  717. int i = cursor - 1;
  718. if (i < 0)
  719. throw new NoSuchElementException();
  720. Object[] elementData = ArrayList.this.elementData;
  721. if (i >= elementData.length)
  722. throw new ConcurrentModificationException();
  723. cursor = i;
  724. return (E) elementData[lastRet = i];
  725. }
  726. public void set(E e) {
  727. if (lastRet < 0)
  728. throw new IllegalStateException();
  729. checkForComodification();
  730. try {
  731. ArrayList.this.set(lastRet, e);
  732. } catch (IndexOutOfBoundsException ex) {
  733. throw new ConcurrentModificationException();
  734. }
  735. }
  736. public void add(E e) {
  737. checkForComodification();
  738. try {
  739. int i = cursor;
  740. ArrayList.this.add(i, e);
  741. cursor = i + 1;
  742. lastRet = -1;
  743. expectedModCount = modCount;
  744. } catch (IndexOutOfBoundsException ex) {
  745. throw new ConcurrentModificationException();
  746. }
  747. }
  748. }
  749. /**
  750. * Returns a view of the portion of this list between the specified
  751. * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. (If
  752. * {@code fromIndex} and {@code toIndex} are equal, the returned list is
  753. * empty.) The returned list is backed by this list, so non-structural
  754. * changes in the returned list are reflected in this list, and vice-versa.
  755. * The returned list supports all of the optional list operations.
  756. *
  757. * <p>This method eliminates the need for explicit range operations (of
  758. * the sort that commonly exist for arrays). Any operation that expects
  759. * a list can be used as a range operation by passing a subList view
  760. * instead of a whole list. For example, the following idiom
  761. * removes a range of elements from a list:
  762. * <pre>
  763. * list.subList(from, to).clear();
  764. * </pre>
  765. * Similar idioms may be constructed for {@link #indexOf(Object)} and
  766. * {@link #lastIndexOf(Object)}, and all of the algorithms in the
  767. * {@link Collections} class can be applied to a subList.
  768. *
  769. * <p>The semantics of the list returned by this method become undefined if
  770. * the backing list (i.e., this list) is <i>structurally modified</i> in
  771. * any way other than via the returned list. (Structural modifications are
  772. * those that change the size of this list, or otherwise perturb it in such
  773. * a fashion that iterations in progress may yield incorrect results.)
  774. *
  775. * @throws IndexOutOfBoundsException {@inheritDoc}
  776. * @throws IllegalArgumentException {@inheritDoc}
  777. */
  778. public List<E> subList(int fromIndex, int toIndex) {
  779. subListRangeCheck(fromIndex, toIndex, size);
  780. return new SubList(this, 0, fromIndex, toIndex);
  781. }
  782. static void subListRangeCheck(int fromIndex, int toIndex, int size) {
  783. if (fromIndex < 0)
  784. throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
  785. if (toIndex > size)
  786. throw new IndexOutOfBoundsException("toIndex = " + toIndex);
  787. if (fromIndex > toIndex)
  788. throw new IllegalArgumentException("fromIndex(" + fromIndex +
  789. ") > toIndex(" + toIndex + ")");
  790. }
  791. private class SubList extends AbstractList<E> implements RandomAccess {
  792. private final AbstractList<E> parent;
  793. private final int parentOffset;
  794. private final int offset;
  795. int size;
  796. SubList(AbstractList<E> parent,
  797. int offset, int fromIndex, int toIndex) {
  798. this.parent = parent;
  799. this.parentOffset = fromIndex;
  800. this.offset = offset + fromIndex;
  801. this.size = toIndex - fromIndex;
  802. this.modCount = ArrayList.this.modCount;
  803. }
  804. public E set(int index, E e) {
  805. rangeCheck(index);
  806. checkForComodification();
  807. E oldValue = ArrayList.this.elementData(offset + index);
  808. ArrayList.this.elementData[offset + index] = e;
  809. return oldValue;
  810. }
  811. public E get(int index) {
  812. rangeCheck(index);
  813. checkForComodification();
  814. return ArrayList.this.elementData(offset + index);
  815. }
  816. public int size() {
  817. checkForComodification();
  818. return this.size;
  819. }
  820. public void add(int index, E e) {
  821. rangeCheckForAdd(index);
  822. checkForComodification();
  823. parent.add(parentOffset + index, e);
  824. this.modCount = parent.modCount;
  825. this.size++;
  826. }
  827. public E remove(int index) {
  828. rangeCheck(index);
  829. checkForComodification();
  830. E result = parent.remove(parentOffset + index);
  831. this.modCount = parent.modCount;
  832. this.size--;
  833. return result;
  834. }
  835. protected void removeRange(int fromIndex, int toIndex) {
  836. checkForComodification();
  837. parent.removeRange(parentOffset + fromIndex,
  838. parentOffset + toIndex);
  839. this.modCount = parent.modCount;
  840. this.size -= toIndex - fromIndex;
  841. }
  842. public boolean addAll(Collection<? extends E> c) {
  843. return addAll(this.size, c);
  844. }
  845. public boolean addAll(int index, Collection<? extends E> c) {
  846. rangeCheckForAdd(index);
  847. int cSize = c.size();
  848. if (cSize==0)
  849. return false;
  850. checkForComodification();
  851. parent.addAll(parentOffset + index, c);
  852. this.modCount = parent.modCount;
  853. this.size += cSize;
  854. return true;
  855. }
  856. public Iterator<E> iterator() {
  857. return listIterator();
  858. }
  859. public ListIterator<E> listIterator(final int index) {
  860. checkForComodification();
  861. rangeCheckForAdd(index);
  862. final int offset = this.offset;
  863. return new ListIterator<E>() {
  864. int cursor = index;
  865. int lastRet = -1;
  866. int expectedModCount = ArrayList.this.modCount;
  867. public boolean hasNext() {
  868. return cursor != SubList.this.size;
  869. }
  870. @SuppressWarnings("unchecked")
  871. public E next() {
  872. checkForComodification();
  873. int i = cursor;
  874. if (i >= SubList.this.size)
  875. throw new NoSuchElementException();
  876. Object[] elementData = ArrayList.this.elementData;
  877. if (offset + i >= elementData.length)
  878. throw new ConcurrentModificationException();
  879. cursor = i + 1;
  880. return (E) elementData[offset + (lastRet = i)];
  881. }
  882. public boolean hasPrevious() {
  883. return cursor != 0;
  884. }
  885. @SuppressWarnings("unchecked")
  886. public E previous() {
  887. checkForComodification();
  888. int i = cursor - 1;
  889. if (i < 0)
  890. throw new NoSuchElementException();
  891. Object[] elementData = ArrayList.this.elementData;
  892. if (offset + i >= elementData.length)
  893. throw new ConcurrentModificationException();
  894. cursor = i;
  895. return (E) elementData[offset + (lastRet = i)];
  896. }
  897. public int nextIndex() {
  898. return cursor;
  899. }
  900. public int previousIndex() {
  901. return cursor - 1;
  902. }
  903. public void remove() {
  904. if (lastRet < 0)
  905. throw new IllegalStateException();
  906. checkForComodification();
  907. try {
  908. SubList.this.remove(lastRet);
  909. cursor = lastRet;
  910. lastRet = -1;
  911. expectedModCount = ArrayList.this.modCount;
  912. } catch (IndexOutOfBoundsException ex) {
  913. throw new ConcurrentModificationException();
  914. }
  915. }
  916. public void set(E e) {
  917. if (lastRet < 0)
  918. throw new IllegalStateException();
  919. checkForComodification();
  920. try {
  921. ArrayList.this.set(offset + lastRet, e);
  922. } catch (IndexOutOfBoundsException ex) {
  923. throw new ConcurrentModificationException();
  924. }
  925. }
  926. public void add(E e) {
  927. checkForComodification();
  928. try {
  929. int i = cursor;
  930. SubList.this.add(i, e);
  931. cursor = i + 1;
  932. lastRet = -1;
  933. expectedModCount = ArrayList.this.modCount;
  934. } catch (IndexOutOfBoundsException ex) {
  935. throw new ConcurrentModificationException();
  936. }
  937. }
  938. final void checkForComodification() {
  939. if (expectedModCount != ArrayList.this.modCount)
  940. throw new ConcurrentModificationException();
  941. }
  942. };
  943. }
  944. public List<E> subList(int fromIndex, int toIndex) {
  945. subListRangeCheck(fromIndex, toIndex, size);
  946. return new SubList(this, offset, fromIndex, toIndex);
  947. }
  948. private void rangeCheck(int index) {
  949. if (index < 0 || index >= this.size)
  950. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  951. }
  952. private void rangeCheckForAdd(int index) {
  953. if (index < 0 || index > this.size)
  954. throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
  955. }
  956. private String outOfBoundsMsg(int index) {
  957. return "Index: "+index+", Size: "+this.size;
  958. }
  959. private void checkForComodification() {
  960. if (ArrayList.this.modCount != this.modCount)
  961. throw new ConcurrentModificationException();
  962. }
  963. }
  964. public static void main(String[] args) {
  965. }
  966. }