001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4; 018 019import java.util.Collection; 020import java.util.Iterator; 021import java.util.Set; 022 023/** 024 * Defines a collection that counts the number of times an object appears in 025 * the collection. 026 * <p> 027 * Suppose you have a MultiSet that contains <code>{a, a, b, c}</code>. 028 * Calling {@link #getCount(Object)} on <code>a</code> would return 2, while 029 * calling {@link #uniqueSet()} would return <code>{a, b, c}</code>. 030 * 031 * @param <E> the type held in the multiset 032 * @since 4.1 033 */ 034public interface MultiSet<E> extends Collection<E> { 035 036 /** 037 * Returns the number of occurrences of the given object currently 038 * in the MultiSet. If the object does not exist in the multiset, 039 * return 0. 040 * 041 * @param object the object to search for 042 * @return the number of occurrences of the object, zero if not found 043 */ 044 int getCount(Object object); 045 046 /** 047 * Sets the number of occurrences of the specified object in the MultiSet 048 * to the given count. 049 * <p> 050 * If the provided count is zero, the object will be removed from the 051 * {@link #uniqueSet()}. 052 * 053 * @param object the object to update 054 * @param count the number of occurrences of the object 055 * @return the number of occurrences of the object before this operation, zero 056 * if the object was not contained in the multiset 057 * @throws IllegalArgumentException if count is negative 058 */ 059 int setCount(E object, int count); 060 061 /** 062 * Adds one copy of the specified object to the MultiSet. 063 * <p> 064 * If the object is already in the {@link #uniqueSet()} then increment its 065 * count as reported by {@link #getCount(Object)}. Otherwise add it to the 066 * {@link #uniqueSet()} and report its count as 1. 067 * 068 * @param object the object to add 069 * @return <code>true</code> always, as the size of the MultiSet is increased 070 * in any case 071 */ 072 @Override 073 boolean add(E object); 074 075 /** 076 * Adds a number of occurrences of the specified object to the MultiSet. 077 * <p> 078 * If the object is already in the {@link #uniqueSet()} then increment its 079 * count as reported by {@link #getCount(Object)}. Otherwise add it to the 080 * {@link #uniqueSet()} and report its count as <code>occurrences</code>. 081 * 082 * @param object the object to add 083 * @param occurrences the number of occurrences to add, may be zero, 084 * in which case no change is made to the multiset 085 * @return the number of occurrences of the object in the multiset before 086 * this operation; possibly zero 087 * @throws IllegalArgumentException if occurrences is negative 088 */ 089 int add(E object, int occurrences); 090 091 /** 092 * Removes one occurrence of the given object from the MultiSet. 093 * <p> 094 * If the number of occurrences after this operations is reduced 095 * to zero, the object will be removed from the {@link #uniqueSet()}. 096 * 097 * @param object the object to remove 098 * @return <code>true</code> if this call changed the collection 099 */ 100 @Override 101 boolean remove(Object object); 102 103 /** 104 * Removes a number of occurrences of the specified object from the MultiSet. 105 * <p> 106 * If the number of occurrences to remove is greater than the actual number of 107 * occurrences in the multiset, the object will be removed from the multiset. 108 * 109 * @param object the object to remove 110 * @param occurrences the number of occurrences to remove, may be zero, 111 * in which case no change is made to the multiset 112 * @return the number of occurrences of the object in the multiset 113 * before the operation; possibly zero 114 * @throws IllegalArgumentException if occurrences is negative 115 */ 116 int remove(Object object, int occurrences); 117 118 /** 119 * Returns a {@link Set} of unique elements in the MultiSet. 120 * <p> 121 * Uniqueness constraints are the same as those in {@link java.util.Set}. 122 * <p> 123 * The returned set is backed by this multiset, so any change to either 124 * is immediately reflected in the other. Only removal operations are 125 * supported, in which case all occurrences of the element are removed 126 * from the backing multiset. 127 * 128 * @return the Set of unique MultiSet elements 129 */ 130 Set<E> uniqueSet(); 131 132 /** 133 * Returns a {@link Set} of all entries contained in the MultiSet. 134 * <p> 135 * The returned set is backed by this multiset, so any change to either 136 * is immediately reflected in the other. 137 * 138 * @return the Set of MultiSet entries 139 */ 140 Set<Entry<E>> entrySet(); 141 142 /** 143 * Returns an {@link Iterator} over the entire set of members, 144 * including copies due to cardinality. This iterator is fail-fast 145 * and will not tolerate concurrent modifications. 146 * 147 * @return iterator over all elements in the MultiSet 148 */ 149 @Override 150 Iterator<E> iterator(); 151 152 /** 153 * Returns the total number of items in the MultiSet. 154 * 155 * @return the total size of the multiset 156 */ 157 @Override 158 int size(); 159 160 /** 161 * Returns <code>true</code> if the MultiSet contains at least one 162 * occurrence for each element contained in the given collection. 163 * 164 * @param coll the collection to check against 165 * @return <code>true</code> if the MultiSet contains all the collection 166 */ 167 @Override 168 boolean containsAll(Collection<?> coll); 169 170 /** 171 * Remove all occurrences of all elements from this MultiSet represented 172 * in the given collection. 173 * 174 * @param coll the collection of elements to remove 175 * @return <code>true</code> if this call changed the multiset 176 */ 177 @Override 178 boolean removeAll(Collection<?> coll); 179 180 /** 181 * Remove any elements of this MultiSet that are not contained in the 182 * given collection. 183 * 184 * @param coll the collection of elements to retain 185 * @return <code>true</code> if this call changed the multiset 186 */ 187 @Override 188 boolean retainAll(Collection<?> coll); 189 190 /** 191 * Compares this MultiSet to another object. 192 * <p> 193 * This MultiSet equals another object if it is also a MultiSet 194 * that contains the same number of occurrences of the same elements. 195 * 196 * @param obj the object to compare to 197 * @return true if equal 198 */ 199 @Override 200 boolean equals(Object obj); 201 202 /** 203 * Gets a hash code for the MultiSet compatible with the definition of equals. 204 * The hash code is defined as the sum total of a hash code for each element. 205 * The per element hash code is defined as 206 * <code>(e==null ? 0 : e.hashCode()) ^ noOccurances)</code>. 207 * 208 * @return the hash code of the MultiSet 209 */ 210 @Override 211 int hashCode(); 212 213 /** 214 * An unmodifiable entry for an element and its occurrence as contained in a MultiSet. 215 * <p> 216 * The {@link MultiSet#entrySet()} method returns a view of the multiset whose elements 217 * implements this interface. 218 * 219 * @param <E> the element type 220 */ 221 interface Entry<E> { 222 223 /** 224 * Returns the element corresponding to this entry. 225 * 226 * @return the element corresponding to this entry 227 */ 228 E getElement(); 229 230 /** 231 * Returns the number of occurrences for the element of this entry. 232 * 233 * @return the number of occurrences of the element 234 */ 235 int getCount(); 236 237 /** 238 * Compares the specified object with this entry for equality. 239 * Returns true if the given object is also a multiset entry 240 * and the two entries represent the same element with the same 241 * number of occurrences. 242 * <p> 243 * More formally, two entries <code>e1</code> and <code>e2</code> represent 244 * the same mapping if 245 * <pre> 246 * (e1.getElement()==null ? e2.getElement()==null 247 * : e1.getElement().equals(e2.getElement())) && 248 * (e1.getCount()==e2.getCount()) 249 * </pre> 250 * 251 * @param o object to be compared for equality with this multiset entry 252 * @return true if the specified object is equal to this multiset entry 253 */ 254 @Override 255 boolean equals(Object o); 256 257 /** 258 * Returns the hash code value for this multiset entry. 259 * <p> 260 * The hash code of a multiset entry <code>e</code> is defined to be: 261 * <pre> 262 * (e==null ? 0 : e.hashCode()) ^ noOccurances) 263 * </pre> 264 * 265 * @return the hash code value for this multiset entry 266 */ 267 @Override 268 int hashCode(); 269 } 270 271}