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