1. /*
  2. * @(#)AbstractCollection.java 1.31 03/12/19
  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>Collection</tt>
  10. * interface, to minimize the effort required to implement this interface. <p>
  11. *
  12. * To implement an unmodifiable collection, the programmer needs only to
  13. * extend this class and provide implementations for the <tt>iterator</tt> and
  14. * <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt>
  15. * method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p>
  16. *
  17. * To implement a modifiable collection, the programmer must additionally
  18. * override this class's <tt>add</tt> method (which otherwise throws an
  19. * <tt>UnsupportedOperationException</tt>), and the iterator returned by the
  20. * <tt>iterator</tt> method must additionally implement its <tt>remove</tt>
  21. * method.<p>
  22. *
  23. * The programmer should generally provide a void (no argument) and
  24. * <tt>Collection</tt> constructor, as per the recommendation in the
  25. * <tt>Collection</tt> interface specification.<p>
  26. *
  27. * The documentation for each non-abstract methods in this class describes its
  28. * implementation in detail. Each of these methods may be overridden if
  29. * the collection being implemented admits a more efficient implementation.<p>
  30. *
  31. * This class is a member of the
  32. * <a href="{@docRoot}/../guide/collections/index.html">
  33. * Java Collections Framework</a>.
  34. *
  35. * @author Josh Bloch
  36. * @author Neal Gafter
  37. * @version 1.24, 01/18/03
  38. * @see Collection
  39. * @since 1.2
  40. */
  41. public abstract class AbstractCollection<E> implements Collection<E> {
  42. /**
  43. * Sole constructor. (For invocation by subclass constructors, typically
  44. * implicit.)
  45. */
  46. protected AbstractCollection() {
  47. }
  48. // Query Operations
  49. /**
  50. * Returns an iterator over the elements contained in this collection.
  51. *
  52. * @return an iterator over the elements contained in this collection.
  53. */
  54. public abstract Iterator<E> iterator();
  55. /**
  56. * Returns the number of elements in this collection. If the collection
  57. * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
  58. * <tt>Integer.MAX_VALUE</tt>.
  59. *
  60. * @return the number of elements in this collection.
  61. */
  62. public abstract int size();
  63. /**
  64. * Returns <tt>true</tt> if this collection contains no elements.<p>
  65. *
  66. * This implementation returns <tt>size() == 0</tt>.
  67. *
  68. * @return <tt>true</tt> if this collection contains no elements.
  69. */
  70. public boolean isEmpty() {
  71. return size() == 0;
  72. }
  73. /**
  74. * Returns <tt>true</tt> if this collection contains the specified
  75. * element. More formally, returns <tt>true</tt> if and only if this
  76. * collection contains at least one element <tt>e</tt> such that
  77. * <tt>(o==null ? e==null : o.equals(e))</tt>.<p>
  78. *
  79. * This implementation iterates over the elements in the collection,
  80. * checking each element in turn for equality with the specified element.
  81. *
  82. * @param o object to be checked for containment in this collection.
  83. * @return <tt>true</tt> if this collection contains the specified element.
  84. */
  85. public boolean contains(Object o) {
  86. Iterator<E> e = iterator();
  87. if (o==null) {
  88. while (e.hasNext())
  89. if (e.next()==null)
  90. return true;
  91. } else {
  92. while (e.hasNext())
  93. if (o.equals(e.next()))
  94. return true;
  95. }
  96. return false;
  97. }
  98. /**
  99. * Returns an array containing all of the elements in this collection. If
  100. * the collection makes any guarantees as to what order its elements are
  101. * returned by its iterator, this method must return the elements in the
  102. * same order. The returned array will be "safe" in that no references to
  103. * it are maintained by the collection. (In other words, this method must
  104. * allocate a new array even if the collection is backed by an Array).
  105. * The caller is thus free to modify the returned array.<p>
  106. *
  107. * This implementation allocates the array to be returned, and iterates
  108. * over the elements in the collection, storing each object reference in
  109. * the next consecutive element of the array, starting with element 0.
  110. *
  111. * @return an array containing all of the elements in this collection.
  112. */
  113. public Object[] toArray() {
  114. Object[] result = new Object[size()];
  115. Iterator<E> e = iterator();
  116. for (int i=0; e.hasNext(); i++)
  117. result[i] = e.next();
  118. return result;
  119. }
  120. /**
  121. * Returns an array containing all of the elements in this collection;
  122. * the runtime type of the returned array is that of the specified array.
  123. * If the collection fits in the specified array, it is returned therein.
  124. * Otherwise, a new array is allocated with the runtime type of the
  125. * specified array and the size of this collection.<p>
  126. *
  127. * If the collection fits in the specified array with room to spare (i.e.,
  128. * the array has more elements than the collection), the element in the
  129. * array immediately following the end of the collection is set to
  130. * <tt>null</tt>. This is useful in determining the length of the
  131. * collection <i>only</i> if the caller knows that the collection does
  132. * not contain any <tt>null</tt> elements.)<p>
  133. *
  134. * If this collection makes any guarantees as to what order its elements
  135. * are returned by its iterator, this method must return the elements in
  136. * the same order. <p>
  137. *
  138. * This implementation checks if the array is large enough to contain the
  139. * collection; if not, it allocates a new array of the correct size and
  140. * type (using reflection). Then, it iterates over the collection,
  141. * storing each object reference in the next consecutive element of the
  142. * array, starting with element 0. If the array is larger than the
  143. * collection, a <tt>null</tt> is stored in the first location after the
  144. * end of the collection.
  145. *
  146. * @param a the array into which the elements of the collection are to
  147. * be stored, if it is big enough; otherwise, a new array of the
  148. * same runtime type is allocated for this purpose.
  149. * @return an array containing the elements of the collection.
  150. *
  151. * @throws NullPointerException if the specified array is <tt>null</tt>.
  152. *
  153. * @throws ArrayStoreException if the runtime type of the specified array
  154. * is not a supertype of the runtime type of every element in this
  155. * collection.
  156. */
  157. public <T> T[] toArray(T[] a) {
  158. int size = size();
  159. if (a.length < size)
  160. a = (T[])java.lang.reflect.Array
  161. .newInstance(a.getClass().getComponentType(), size);
  162. Iterator<E> it=iterator();
  163. Object[] result = a;
  164. for (int i=0; i<size; i++)
  165. result[i] = it.next();
  166. if (a.length > size)
  167. a[size] = null;
  168. return a;
  169. }
  170. // Modification Operations
  171. /**
  172. * Ensures that this collection contains the specified element (optional
  173. * operation). Returns <tt>true</tt> if the collection changed as a
  174. * result of the call. (Returns <tt>false</tt> if this collection does
  175. * not permit duplicates and already contains the specified element.)
  176. * Collections that support this operation may place limitations on what
  177. * elements may be added to the collection. In particular, some
  178. * collections will refuse to add <tt>null</tt> elements, and others will
  179. * impose restrictions on the type of elements that may be added.
  180. * Collection classes should clearly specify in their documentation any
  181. * restrictions on what elements may be added.<p>
  182. *
  183. * This implementation always throws an
  184. * <tt>UnsupportedOperationException</tt>.
  185. *
  186. * @param o element whose presence in this collection is to be ensured.
  187. * @return <tt>true</tt> if the collection changed as a result of the call.
  188. *
  189. * @throws UnsupportedOperationException if the <tt>add</tt> method is not
  190. * supported by this collection.
  191. *
  192. * @throws NullPointerException if this collection does not permit
  193. * <tt>null</tt> elements, and the specified element is
  194. * <tt>null</tt>.
  195. *
  196. * @throws ClassCastException if the class of the specified element
  197. * prevents it from being added to this collection.
  198. *
  199. * @throws IllegalArgumentException if some aspect of this element
  200. * prevents it from being added to this collection.
  201. */
  202. public boolean add(E o) {
  203. throw new UnsupportedOperationException();
  204. }
  205. /**
  206. * Removes a single instance of the specified element from this
  207. * collection, if it is present (optional operation). More formally,
  208. * removes an element <tt>e</tt> such that <tt>(o==null ? e==null :
  209. * o.equals(e))</tt>, if the collection contains one or more such
  210. * elements. Returns <tt>true</tt> if the collection contained the
  211. * specified element (or equivalently, if the collection changed as a
  212. * result of the call).<p>
  213. *
  214. * This implementation iterates over the collection looking for the
  215. * specified element. If it finds the element, it removes the element
  216. * from the collection using the iterator's remove method.<p>
  217. *
  218. * Note that this implementation throws an
  219. * <tt>UnsupportedOperationException</tt> if the iterator returned by this
  220. * collection's iterator method does not implement the <tt>remove</tt>
  221. * method and this collection contains the specified object.
  222. *
  223. * @param o element to be removed from this collection, if present.
  224. * @return <tt>true</tt> if the collection contained the specified
  225. * element.
  226. * @throws UnsupportedOperationException if the <tt>remove</tt> method is
  227. * not supported by this collection.
  228. */
  229. public boolean remove(Object o) {
  230. Iterator<E> e = iterator();
  231. if (o==null) {
  232. while (e.hasNext()) {
  233. if (e.next()==null) {
  234. e.remove();
  235. return true;
  236. }
  237. }
  238. } else {
  239. while (e.hasNext()) {
  240. if (o.equals(e.next())) {
  241. e.remove();
  242. return true;
  243. }
  244. }
  245. }
  246. return false;
  247. }
  248. // Bulk Operations
  249. /**
  250. * Returns <tt>true</tt> if this collection contains all of the elements
  251. * in the specified collection. <p>
  252. *
  253. * This implementation iterates over the specified collection, checking
  254. * each element returned by the iterator in turn to see if it's
  255. * contained in this collection. If all elements are so contained
  256. * <tt>true</tt> is returned, otherwise <tt>false</tt>.
  257. *
  258. * @param c collection to be checked for containment in this collection.
  259. * @return <tt>true</tt> if this collection contains all of the elements
  260. * in the specified collection.
  261. * @throws NullPointerException if the specified collection is null.
  262. *
  263. * @see #contains(Object)
  264. */
  265. public boolean containsAll(Collection<?> c) {
  266. Iterator<?> e = c.iterator();
  267. while (e.hasNext())
  268. if(!contains(e.next()))
  269. return false;
  270. return true;
  271. }
  272. /**
  273. * Adds all of the elements in the specified collection to this collection
  274. * (optional operation). The behavior of this operation is undefined if
  275. * the specified collection is modified while the operation is in
  276. * progress. (This implies that the behavior of this call is undefined if
  277. * the specified collection is this collection, and this collection is
  278. * nonempty.) <p>
  279. *
  280. * This implementation iterates over the specified collection, and adds
  281. * each object returned by the iterator to this collection, in turn.<p>
  282. *
  283. * Note that this implementation will throw an
  284. * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is
  285. * overridden (assuming the specified collection is non-empty).
  286. *
  287. * @param c collection whose elements are to be added to this collection.
  288. * @return <tt>true</tt> if this collection changed as a result of the
  289. * call.
  290. * @throws UnsupportedOperationException if this collection does not
  291. * support the <tt>addAll</tt> method.
  292. * @throws NullPointerException if the specified collection is null.
  293. *
  294. * @see #add(Object)
  295. */
  296. public boolean addAll(Collection<? extends E> c) {
  297. boolean modified = false;
  298. Iterator<? extends E> e = c.iterator();
  299. while (e.hasNext()) {
  300. if (add(e.next()))
  301. modified = true;
  302. }
  303. return modified;
  304. }
  305. /**
  306. * Removes from this collection all of its elements that are contained in
  307. * the specified collection (optional operation). <p>
  308. *
  309. * This implementation iterates over this collection, checking each
  310. * element returned by the iterator in turn to see if it's contained
  311. * in the specified collection. If it's so contained, it's removed from
  312. * this collection with the iterator's <tt>remove</tt> method.<p>
  313. *
  314. * Note that this implementation will throw an
  315. * <tt>UnsupportedOperationException</tt> if the iterator returned by the
  316. * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
  317. * and this collection contains one or more elements in common with the
  318. * specified collection.
  319. *
  320. * @param c elements to be removed from this collection.
  321. * @return <tt>true</tt> if this collection changed as a result of the
  322. * call.
  323. * @throws UnsupportedOperationException if the <tt>removeAll</tt> method
  324. * is not supported by this collection.
  325. * @throws NullPointerException if the specified collection is null.
  326. *
  327. * @see #remove(Object)
  328. * @see #contains(Object)
  329. */
  330. public boolean removeAll(Collection<?> c) {
  331. boolean modified = false;
  332. Iterator<?> e = iterator();
  333. while (e.hasNext()) {
  334. if (c.contains(e.next())) {
  335. e.remove();
  336. modified = true;
  337. }
  338. }
  339. return modified;
  340. }
  341. /**
  342. * Retains only the elements in this collection that are contained in the
  343. * specified collection (optional operation). In other words, removes
  344. * from this collection all of its elements that are not contained in the
  345. * specified collection. <p>
  346. *
  347. * This implementation iterates over this collection, checking each
  348. * element returned by the iterator in turn to see if it's contained
  349. * in the specified collection. If it's not so contained, it's removed
  350. * from this collection with the iterator's <tt>remove</tt> method.<p>
  351. *
  352. * Note that this implementation will throw an
  353. * <tt>UnsupportedOperationException</tt> if the iterator returned by the
  354. * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
  355. * and this collection contains one or more elements not present in the
  356. * specified collection.
  357. *
  358. * @param c elements to be retained in this collection.
  359. * @return <tt>true</tt> if this collection changed as a result of the
  360. * call.
  361. * @throws UnsupportedOperationException if the <tt>retainAll</tt> method
  362. * is not supported by this Collection.
  363. * @throws NullPointerException if the specified collection is null.
  364. *
  365. * @see #remove(Object)
  366. * @see #contains(Object)
  367. */
  368. public boolean retainAll(Collection<?> c) {
  369. boolean modified = false;
  370. Iterator<E> e = iterator();
  371. while (e.hasNext()) {
  372. if (!c.contains(e.next())) {
  373. e.remove();
  374. modified = true;
  375. }
  376. }
  377. return modified;
  378. }
  379. /**
  380. * Removes all of the elements from this collection (optional operation).
  381. * The collection will be empty after this call returns (unless it throws
  382. * an exception).<p>
  383. *
  384. * This implementation iterates over this collection, removing each
  385. * element using the <tt>Iterator.remove</tt> operation. Most
  386. * implementations will probably choose to override this method for
  387. * efficiency.<p>
  388. *
  389. * Note that this implementation will throw an
  390. * <tt>UnsupportedOperationException</tt> if the iterator returned by this
  391. * collection's <tt>iterator</tt> method does not implement the
  392. * <tt>remove</tt> method and this collection is non-empty.
  393. *
  394. * @throws UnsupportedOperationException if the <tt>clear</tt> method is
  395. * not supported by this collection.
  396. */
  397. public void clear() {
  398. Iterator<E> e = iterator();
  399. while (e.hasNext()) {
  400. e.next();
  401. e.remove();
  402. }
  403. }
  404. // String conversion
  405. /**
  406. * Returns a string representation of this collection. The string
  407. * representation consists of a list of the collection's elements in the
  408. * order they are returned by its iterator, enclosed in square brackets
  409. * (<tt>"[]"</tt>). Adjacent elements are separated by the characters
  410. * <tt>", "</tt> (comma and space). Elements are converted to strings as
  411. * by <tt>String.valueOf(Object)</tt>.<p>
  412. *
  413. * This implementation creates an empty string buffer, appends a left
  414. * square bracket, and iterates over the collection appending the string
  415. * representation of each element in turn. After appending each element
  416. * except the last, the string <tt>", "</tt> is appended. Finally a right
  417. * bracket is appended. A string is obtained from the string buffer, and
  418. * returned.
  419. *
  420. * @return a string representation of this collection.
  421. */
  422. public String toString() {
  423. StringBuffer buf = new StringBuffer();
  424. buf.append("[");
  425. Iterator<E> i = iterator();
  426. boolean hasNext = i.hasNext();
  427. while (hasNext) {
  428. E o = i.next();
  429. buf.append(o == this ? "(this Collection)" : String.valueOf(o));
  430. hasNext = i.hasNext();
  431. if (hasNext)
  432. buf.append(", ");
  433. }
  434. buf.append("]");
  435. return buf.toString();
  436. }
  437. }