1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.collections;
  17. import java.util.Collection;
  18. import java.util.Iterator;
  19. import java.util.Set;
  20. /**
  21. * Defines a collection that counts the number of times an object appears in
  22. * the collection.
  23. * <p>
  24. * Suppose you have a Bag that contains <code>{a, a, b, c}</code>.
  25. * Calling {@link #getCount(Object)} on <code>a</code> would return 2, while
  26. * calling {@link #uniqueSet()} would return <code>{a, b, c}</code>.
  27. * <p>
  28. * <i>NOTE: This interface violates the {@link Collection} contract.</i>
  29. * The behavior specified in many of these methods is <i>not</i> the same
  30. * as the behavior specified by <code>Collection</code>.
  31. * The noncompliant methods are clearly marked with "(Violation)".
  32. * Exercise caution when using a bag as a <code>Collection</code>.
  33. * <p>
  34. * This violation resulted from the original specification of this interface.
  35. * In an ideal world, the interface would be changed to fix the problems, however
  36. * it has been decided to maintain backwards compatibility instead.
  37. *
  38. * @since Commons Collections 2.0
  39. * @version $Revision: 1.18 $ $Date: 2004/05/03 15:12:20 $
  40. *
  41. * @author Chuck Burdick
  42. * @author Stephen Colebourne
  43. */
  44. public interface Bag extends Collection {
  45. /**
  46. * Returns the number of occurrences (cardinality) of the given
  47. * object currently in the bag. If the object does not exist in the
  48. * bag, return 0.
  49. *
  50. * @param object the object to search for
  51. * @return the number of occurrences of the object, zero if not found
  52. */
  53. int getCount(Object object);
  54. /**
  55. * <i>(Violation)</i>
  56. * Adds one copy the specified object to the Bag.
  57. * <p>
  58. * If the object is already in the {@link #uniqueSet()} then increment its
  59. * count as reported by {@link #getCount(Object)}. Otherwise add it to the
  60. * {@link #uniqueSet()} and report its count as 1.
  61. * <p>
  62. * Since this method always increases the size of the bag,
  63. * according to the {@link Collection#add(Object)} contract, it
  64. * should always return <code>true</code>. Since it sometimes returns
  65. * <code>false</code>, this method violates the contract.
  66. *
  67. * @param object the object to add
  68. * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
  69. */
  70. boolean add(Object object);
  71. /**
  72. * Adds <code>nCopies</code> copies of the specified object to the Bag.
  73. * <p>
  74. * If the object is already in the {@link #uniqueSet()} then increment its
  75. * count as reported by {@link #getCount(Object)}. Otherwise add it to the
  76. * {@link #uniqueSet()} and report its count as <code>nCopies</code>.
  77. *
  78. * @param object the object to add
  79. * @param nCopies the number of copies to add
  80. * @return <code>true</code> if the object was not already in the <code>uniqueSet</code>
  81. */
  82. boolean add(Object object, int nCopies);
  83. /**
  84. * <i>(Violation)</i>
  85. * Removes all occurrences of the given object from the bag.
  86. * <p>
  87. * This will also remove the object from the {@link #uniqueSet()}.
  88. * <p>
  89. * According to the {@link Collection#remove(Object)} method,
  90. * this method should only remove the <i>first</i> occurrence of the
  91. * given object, not <i>all</i> occurrences.
  92. *
  93. * @return <code>true</code> if this call changed the collection
  94. */
  95. boolean remove(Object object);
  96. /**
  97. * Removes <code>nCopies</code> copies of the specified object from the Bag.
  98. * <p>
  99. * If the number of copies to remove is greater than the actual number of
  100. * copies in the Bag, no error is thrown.
  101. *
  102. * @param object the object to remove
  103. * @param nCopies the number of copies to remove
  104. * @return <code>true</code> if this call changed the collection
  105. */
  106. boolean remove(Object object, int nCopies);
  107. /**
  108. * Returns a {@link Set} of unique elements in the Bag.
  109. * <p>
  110. * Uniqueness constraints are the same as those in {@link java.util.Set}.
  111. *
  112. * @return the Set of unique Bag elements
  113. */
  114. Set uniqueSet();
  115. /**
  116. * Returns the total number of items in the bag across all types.
  117. *
  118. * @return the total size of the Bag
  119. */
  120. int size();
  121. /**
  122. * <i>(Violation)</i>
  123. * Returns <code>true</code> if the bag contains all elements in
  124. * the given collection, respecting cardinality. That is, if the
  125. * given collection <code>coll</code> contains <code>n</code> copies
  126. * of a given object, calling {@link #getCount(Object)} on that object must
  127. * be <code>>= n</code> for all <code>n</code> in <code>coll</code>.
  128. * <p>
  129. * The {@link Collection#containsAll(Collection)} method specifies
  130. * that cardinality should <i>not</i> be respected; this method should
  131. * return true if the bag contains at least one of every object contained
  132. * in the given collection.
  133. *
  134. * @param coll the collection to check against
  135. * @return <code>true</code> if the Bag contains all the collection
  136. */
  137. boolean containsAll(Collection coll);
  138. /**
  139. * <i>(Violation)</i>
  140. * Remove all elements represented in the given collection,
  141. * respecting cardinality. That is, if the given collection
  142. * <code>coll</code> contains <code>n</code> copies of a given object,
  143. * the bag will have <code>n</code> fewer copies, assuming the bag
  144. * had at least <code>n</code> copies to begin with.
  145. *
  146. * <P>The {@link Collection#removeAll(Collection)} method specifies
  147. * that cardinality should <i>not</i> be respected; this method should
  148. * remove <i>all</i> occurrences of every object contained in the
  149. * given collection.
  150. *
  151. * @param coll the collection to remove
  152. * @return <code>true</code> if this call changed the collection
  153. */
  154. boolean removeAll(Collection coll);
  155. /**
  156. * <i>(Violation)</i>
  157. * Remove any members of the bag that are not in the given
  158. * collection, respecting cardinality. That is, if the given
  159. * collection <code>coll</code> contains <code>n</code> copies of a
  160. * given object and the bag has <code>m > n</code> copies, then
  161. * delete <code>m - n</code> copies from the bag. In addition, if
  162. * <code>e</code> is an object in the bag but
  163. * <code>!coll.contains(e)</code>, then remove <code>e</code> and any
  164. * of its copies.
  165. *
  166. * <P>The {@link Collection#retainAll(Collection)} method specifies
  167. * that cardinality should <i>not</i> be respected; this method should
  168. * keep <i>all</i> occurrences of every object contained in the
  169. * given collection.
  170. *
  171. * @param coll the collection to retain
  172. * @return <code>true</code> if this call changed the collection
  173. */
  174. boolean retainAll(Collection coll);
  175. /**
  176. * Returns an {@link Iterator} over the entire set of members,
  177. * including copies due to cardinality. This iterator is fail-fast
  178. * and will not tolerate concurrent modifications.
  179. *
  180. * @return iterator over all elements in the Bag
  181. */
  182. Iterator iterator();
  183. // The following is not part of the formal Bag interface, however where possible
  184. // Bag implementations should follow these comments.
  185. // /**
  186. // * Compares this Bag to another.
  187. // * This Bag equals another Bag if it contains the same number of occurrences of
  188. // * the same elements.
  189. // * This equals definition is compatible with the Set interface.
  190. // *
  191. // * @param obj the Bag to compare to
  192. // * @return true if equal
  193. // */
  194. // boolean equals(Object obj);
  195. //
  196. // /**
  197. // * Gets a hash code for the Bag compatible with the definition of equals.
  198. // * The hash code is defined as the sum total of a hash code for each element.
  199. // * The per element hash code is defined as
  200. // * <code>(e==null ? 0 : e.hashCode()) ^ noOccurances)</code>.
  201. // * This hash code definition is compatible with the Set interface.
  202. // *
  203. // * @return the hash code of the Bag
  204. // */
  205. // int hashCode();
  206. }