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