001 /*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package com.google.common.collect;
018
019 import com.google.common.annotations.Beta;
020 import com.google.common.annotations.GwtCompatible;
021 import com.google.common.base.Objects;
022
023 import java.util.Collection;
024 import java.util.Iterator;
025 import java.util.Set;
026
027 import javax.annotation.Nullable;
028
029 /**
030 * A multiset which forwards all its method calls to another multiset.
031 * Subclasses should override one or more methods to modify the behavior of the
032 * backing multiset as desired per the <a
033 * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
034 *
035 * <p><b>Warning:</b> The methods of {@code ForwardingMultiset} forward
036 * <b>indiscriminately</b> to the methods of the delegate. For example,
037 * overriding {@link #add(Object, int)} alone <b>will not</b> change the
038 * behavior of {@link #add(Object)}, which can lead to unexpected behavior. In
039 * this case, you should override {@code add(Object)} as well, either providing
040 * your own implementation, or delegating to the provided {@code standardAdd}
041 * method.
042 *
043 * <p>The {@code standard} methods and any collection views they return are not
044 * guaranteed to be thread-safe, even when all of the methods that they depend
045 * on are thread-safe.
046 *
047 * @author Kevin Bourrillion
048 * @author Louis Wasserman
049 * @since 2.0 (imported from Google Collections Library)
050 */
051 @GwtCompatible
052 public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
053 implements Multiset<E> {
054
055 /** Constructor for use by subclasses. */
056 protected ForwardingMultiset() {}
057
058
059 @Override
060 protected abstract Multiset<E> delegate();
061
062 public int count(Object element) {
063 return delegate().count(element);
064 }
065
066 public int add(E element, int occurrences) {
067 return delegate().add(element, occurrences);
068 }
069
070 public int remove(Object element, int occurrences) {
071 return delegate().remove(element, occurrences);
072 }
073
074 public Set<E> elementSet() {
075 return delegate().elementSet();
076 }
077
078 public Set<Entry<E>> entrySet() {
079 return delegate().entrySet();
080 }
081
082
083 @Override
084 public boolean equals(@Nullable Object object) {
085 return object == this || delegate().equals(object);
086 }
087
088
089 @Override
090 public int hashCode() {
091 return delegate().hashCode();
092 }
093
094 public int setCount(E element, int count) {
095 return delegate().setCount(element, count);
096 }
097
098 public boolean setCount(E element, int oldCount, int newCount) {
099 return delegate().setCount(element, oldCount, newCount);
100 }
101
102 /**
103 * A sensible definition of {@link #contains} in terms of {@link #count}. If
104 * you override {@link #count}, you may wish to override {@link #contains} to
105 * forward to this implementation.
106 *
107 * @since 7.0
108 */
109
110 @Override
111 @Beta protected boolean standardContains(@Nullable Object object) {
112 return count(object) > 0;
113 }
114
115 /**
116 * A sensible definition of {@link #clear} in terms of the {@code iterator}
117 * method of {@link #entrySet}. If you override {@link #entrySet}, you may
118 * wish to override {@link #clear} to forward to this implementation.
119 *
120 * @since 7.0
121 */
122
123 @Override
124 @Beta protected void standardClear() {
125 Iterator<Entry<E>> entryIterator = entrySet().iterator();
126 while (entryIterator.hasNext()) {
127 entryIterator.next();
128 entryIterator.remove();
129 }
130 }
131
132 /**
133 * A sensible, albeit inefficient, definition of {@link #count} in terms of
134 * {@link #entrySet}. If you override {@link #entrySet}, you may wish to
135 * override {@link #count} to forward to this implementation.
136 *
137 * @since 7.0
138 */
139 @Beta protected int standardCount(@Nullable Object object) {
140 for (Entry<?> entry : this.entrySet()) {
141 if (Objects.equal(entry.getElement(), object)) {
142 return entry.getCount();
143 }
144 }
145 return 0;
146 }
147
148 /**
149 * A sensible definition of {@link #add(Object)} in terms of {@link
150 * #add(Object, int)}. If you override {@link #add(Object, int)}, you may
151 * wish to override {@link #add(Object)} to forward to this implementation.
152 *
153 * @since 7.0
154 */
155 @Beta protected boolean standardAdd(E element) {
156 add(element, 1);
157 return true;
158 }
159
160 /**
161 * A sensible definition of {@link #addAll(Collection)} in terms of {@link
162 * #add(Object)} and {@link #add(Object, int)}. If you override either of
163 * these methods, you may wish to override {@link #addAll(Collection)} to
164 * forward to this implementation.
165 *
166 * @since 7.0
167 */
168
169 @Override
170 @Beta protected boolean standardAddAll(
171 Collection<? extends E> elementsToAdd) {
172 return Multisets.addAllImpl(this, elementsToAdd);
173 }
174
175 /**
176 * A sensible definition of {@link #remove(Object)} in terms of {@link
177 * #remove(Object, int)}. If you override {@link #remove(Object, int)}, you
178 * may wish to override {@link #remove(Object)} to forward to this
179 * implementation.
180 *
181 * @since 7.0
182 */
183
184 @Override
185 @Beta protected boolean standardRemove(Object element) {
186 return remove(element, 1) > 0;
187 }
188
189 /**
190 * A sensible definition of {@link #removeAll} in terms of the {@code
191 * removeAll} method of {@link #elementSet}. If you override {@link
192 * #elementSet}, you may wish to override {@link #removeAll} to forward to
193 * this implementation.
194 *
195 * @since 7.0
196 */
197
198 @Override
199 @Beta protected boolean standardRemoveAll(
200 Collection<?> elementsToRemove) {
201 return Multisets.removeAllImpl(this, elementsToRemove);
202 }
203
204 /**
205 * A sensible definition of {@link #retainAll} in terms of the {@code
206 * retainAll} method of {@link #elementSet}. If you override {@link
207 * #elementSet}, you may wish to override {@link #retainAll} to forward to
208 * this implementation.
209 *
210 * @since 7.0
211 */
212
213 @Override
214 @Beta protected boolean standardRetainAll(
215 Collection<?> elementsToRetain) {
216 return Multisets.retainAllImpl(this, elementsToRetain);
217 }
218
219 /**
220 * A sensible definition of {@link #setCount(Object, int)} in terms of {@link
221 * #count(Object)}, {@link #add(Object, int)}, and {@link #remove(Object,
222 * int)}. {@link #entrySet()}. If you override any of these methods, you may
223 * wish to override {@link #setCount(Object, int)} to forward to this
224 * implementation.
225 *
226 * @since 7.0
227 */
228 @Beta protected int standardSetCount(E element, int count) {
229 return Multisets.setCountImpl(this, element, count);
230 }
231
232 /**
233 * A sensible definition of {@link #setCount(Object, int, int)} in terms of
234 * {@link #count(Object)} and {@link #setCount(Object, int)}. If you override
235 * either of these methods, you may wish to override {@link #setCount(Object,
236 * int, int)} to forward to this implementation.
237 *
238 * @since 7.0
239 */
240 @Beta protected boolean standardSetCount(
241 E element, int oldCount, int newCount) {
242 return Multisets.setCountImpl(this, element, oldCount, newCount);
243 }
244
245 /**
246 * A sensible implementation of {@link Multiset#elementSet} in terms of the
247 * following methods: {@link ForwardingMultiset#clear}, {@link
248 * ForwardingMultiset#contains}, {@link ForwardingMultiset#containsAll},
249 * {@link ForwardingMultiset#count}, {@link ForwardingMultiset#isEmpty}, the
250 * {@link Set#size} and {@link Set#iterator} methods of {@link
251 * ForwardingMultiset#entrySet}, and {@link ForwardingMultiset#remove(Object,
252 * int)}. In many situations, you may wish to override {@link
253 * ForwardingMultiset#elementSet} to forward to this implementation or a
254 * subclass thereof.
255 *
256 * @since 10.0
257 */
258 @Beta
259 protected class StandardElementSet extends Multisets.ElementSet<E> {
260 /** Constructor for use by subclasses. */
261 public StandardElementSet() {}
262
263
264 @Override
265 Multiset<E> multiset() {
266 return ForwardingMultiset.this;
267 }
268 }
269
270 /**
271 * A sensible definition of {@link #iterator} in terms of {@link #entrySet}
272 * and {@link #remove(Object)}. If you override either of these methods, you
273 * may wish to override {@link #iterator} to forward to this implementation.
274 *
275 * @since 7.0
276 */
277 @Beta protected Iterator<E> standardIterator() {
278 return Multisets.iteratorImpl(this);
279 }
280
281 /**
282 * A sensible, albeit inefficient, definition of {@link #size} in terms of
283 * {@link #entrySet}. If you override {@link #entrySet}, you may wish to
284 * override {@link #size} to forward to this implementation.
285 *
286 * @since 7.0
287 */
288 @Beta protected int standardSize() {
289 return Multisets.sizeImpl(this);
290 }
291
292 /**
293 * A sensible, albeit inefficient, definition of {@link #size} in terms of
294 * {@code entrySet().size()} and {@link #count}. If you override either of
295 * these methods, you may wish to override {@link #size} to forward to this
296 * implementation.
297 *
298 * @since 7.0
299 */
300 @Beta protected boolean standardEquals(@Nullable Object object) {
301 return Multisets.equalsImpl(this, object);
302 }
303
304 /**
305 * A sensible definition of {@link #hashCode} as {@code entrySet().hashCode()}
306 * . If you override {@link #entrySet}, you may wish to override {@link
307 * #hashCode} to forward to this implementation.
308 *
309 * @since 7.0
310 */
311 @Beta protected int standardHashCode() {
312 return entrySet().hashCode();
313 }
314
315 /**
316 * A sensible definition of {@link #toString} as {@code entrySet().toString()}
317 * . If you override {@link #entrySet}, you may wish to override {@link
318 * #toString} to forward to this implementation.
319 *
320 * @since 7.0
321 */
322
323 @Override
324 @Beta protected String standardToString() {
325 return entrySet().toString();
326 }
327 }