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