• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
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 
17 package com.google.common.collect;
18 
19 import com.google.common.annotations.Beta;
20 import com.google.common.annotations.GwtCompatible;
21 import com.google.common.base.Objects;
22 
23 import java.util.Collection;
24 import java.util.Iterator;
25 import java.util.Set;
26 
27 import javax.annotation.Nullable;
28 
29 /**
30  * A multiset which forwards all its method calls to another multiset.
31  * Subclasses should override one or more methods to modify the behavior of the
32  * backing multiset as desired per the <a
33  * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
34  *
35  * <p><b>Warning:</b> The methods of {@code ForwardingMultiset} forward
36  * <b>indiscriminately</b> to the methods of the delegate. For example,
37  * overriding {@link #add(Object, int)} alone <b>will not</b> change the
38  * behavior of {@link #add(Object)}, which can lead to unexpected behavior. In
39  * this case, you should override {@code add(Object)} as well, either providing
40  * your own implementation, or delegating to the provided {@code standardAdd}
41  * method.
42  *
43  * <p>The {@code standard} methods and any collection views they return are not
44  * guaranteed to be thread-safe, even when all of the methods that they depend
45  * on are thread-safe.
46  *
47  * @author Kevin Bourrillion
48  * @author Louis Wasserman
49  * @since 2.0 (imported from Google Collections Library)
50  */
51 @GwtCompatible
52 public abstract class ForwardingMultiset<E> extends ForwardingCollection<E>
53     implements Multiset<E> {
54 
55   /** Constructor for use by subclasses. */
ForwardingMultiset()56   protected ForwardingMultiset() {}
57 
delegate()58   @Override protected abstract Multiset<E> delegate();
59 
60   @Override
count(Object element)61   public int count(Object element) {
62     return delegate().count(element);
63   }
64 
65   @Override
add(E element, int occurrences)66   public int add(E element, int occurrences) {
67     return delegate().add(element, occurrences);
68   }
69 
70   @Override
remove(Object element, int occurrences)71   public int remove(Object element, int occurrences) {
72     return delegate().remove(element, occurrences);
73   }
74 
75   @Override
elementSet()76   public Set<E> elementSet() {
77     return delegate().elementSet();
78   }
79 
80   @Override
entrySet()81   public Set<Entry<E>> entrySet() {
82     return delegate().entrySet();
83   }
84 
equals(@ullable Object object)85   @Override public boolean equals(@Nullable Object object) {
86     return object == this || delegate().equals(object);
87   }
88 
hashCode()89   @Override public int hashCode() {
90     return delegate().hashCode();
91   }
92 
93   @Override
setCount(E element, int count)94   public int setCount(E element, int count) {
95     return delegate().setCount(element, count);
96   }
97 
98   @Override
setCount(E element, int oldCount, int newCount)99   public boolean setCount(E element, int oldCount, int newCount) {
100     return delegate().setCount(element, oldCount, newCount);
101   }
102 
103   /**
104    * A sensible definition of {@link #contains} in terms of {@link #count}. If
105    * you override {@link #count}, you may wish to override {@link #contains} to
106    * forward to this implementation.
107    *
108    * @since 7.0
109    */
standardContains(@ullable Object object)110   @Override protected boolean standardContains(@Nullable Object object) {
111     return count(object) > 0;
112   }
113 
114   /**
115    * A sensible definition of {@link #clear} in terms of the {@code iterator}
116    * method of {@link #entrySet}. If you override {@link #entrySet}, you may
117    * wish to override {@link #clear} to forward to this implementation.
118    *
119    * @since 7.0
120    */
standardClear()121   @Override protected void standardClear() {
122     Iterators.clear(entrySet().iterator());
123   }
124 
125   /**
126    * A sensible, albeit inefficient, definition of {@link #count} in terms of
127    * {@link #entrySet}. If you override {@link #entrySet}, you may wish to
128    * override {@link #count} to forward to this implementation.
129    *
130    * @since 7.0
131    */
standardCount(@ullable Object object)132   @Beta protected int standardCount(@Nullable Object object) {
133     for (Entry<?> entry : this.entrySet()) {
134       if (Objects.equal(entry.getElement(), object)) {
135         return entry.getCount();
136       }
137     }
138     return 0;
139   }
140 
141   /**
142    * A sensible definition of {@link #add(Object)} in terms of {@link
143    * #add(Object, int)}. If you override {@link #add(Object, int)}, you may
144    * wish to override {@link #add(Object)} to forward to this implementation.
145    *
146    * @since 7.0
147    */
standardAdd(E element)148   protected boolean standardAdd(E element) {
149     add(element, 1);
150     return true;
151   }
152 
153   /**
154    * A sensible definition of {@link #addAll(Collection)} in terms of {@link
155    * #add(Object)} and {@link #add(Object, int)}. If you override either of
156    * these methods, you may wish to override {@link #addAll(Collection)} to
157    * forward to this implementation.
158    *
159    * @since 7.0
160    */
standardAddAll( Collection<? extends E> elementsToAdd)161   @Beta @Override protected boolean standardAddAll(
162       Collection<? extends E> elementsToAdd) {
163     return Multisets.addAllImpl(this, elementsToAdd);
164   }
165 
166   /**
167    * A sensible definition of {@link #remove(Object)} in terms of {@link
168    * #remove(Object, int)}. If you override {@link #remove(Object, int)}, you
169    * may wish to override {@link #remove(Object)} to forward to this
170    * implementation.
171    *
172    * @since 7.0
173    */
standardRemove(Object element)174   @Override protected boolean standardRemove(Object element) {
175     return remove(element, 1) > 0;
176   }
177 
178   /**
179    * A sensible definition of {@link #removeAll} in terms of the {@code
180    * removeAll} method of {@link #elementSet}. If you override {@link
181    * #elementSet}, you may wish to override {@link #removeAll} to forward to
182    * this implementation.
183    *
184    * @since 7.0
185    */
standardRemoveAll( Collection<?> elementsToRemove)186   @Override protected boolean standardRemoveAll(
187       Collection<?> elementsToRemove) {
188     return Multisets.removeAllImpl(this, elementsToRemove);
189   }
190 
191   /**
192    * A sensible definition of {@link #retainAll} in terms of the {@code
193    * retainAll} method of {@link #elementSet}. If you override {@link
194    * #elementSet}, you may wish to override {@link #retainAll} to forward to
195    * this implementation.
196    *
197    * @since 7.0
198    */
standardRetainAll( Collection<?> elementsToRetain)199   @Override protected boolean standardRetainAll(
200       Collection<?> elementsToRetain) {
201     return Multisets.retainAllImpl(this, elementsToRetain);
202   }
203 
204   /**
205    * A sensible definition of {@link #setCount(Object, int)} in terms of {@link
206    * #count(Object)}, {@link #add(Object, int)}, and {@link #remove(Object,
207    * int)}. {@link #entrySet()}. If you override any of these methods, you may
208    * wish to override {@link #setCount(Object, int)} to forward to this
209    * implementation.
210    *
211    * @since 7.0
212    */
standardSetCount(E element, int count)213   protected int standardSetCount(E element, int count) {
214     return Multisets.setCountImpl(this, element, count);
215   }
216 
217   /**
218    * A sensible definition of {@link #setCount(Object, int, int)} in terms of
219    * {@link #count(Object)} and {@link #setCount(Object, int)}. If you override
220    * either of these methods, you may wish to override {@link #setCount(Object,
221    * int, int)} to forward to this implementation.
222    *
223    * @since 7.0
224    */
standardSetCount(E element, int oldCount, int newCount)225   protected boolean standardSetCount(E element, int oldCount, int newCount) {
226     return Multisets.setCountImpl(this, element, oldCount, newCount);
227   }
228 
229   /**
230    * A sensible implementation of {@link Multiset#elementSet} in terms of the
231    * following methods: {@link ForwardingMultiset#clear}, {@link
232    * ForwardingMultiset#contains}, {@link ForwardingMultiset#containsAll},
233    * {@link ForwardingMultiset#count}, {@link ForwardingMultiset#isEmpty}, the
234    * {@link Set#size} and {@link Set#iterator} methods of {@link
235    * ForwardingMultiset#entrySet}, and {@link ForwardingMultiset#remove(Object,
236    * int)}.  In many situations, you may wish to override {@link
237    * ForwardingMultiset#elementSet} to forward to this implementation or a
238    * subclass thereof.
239    *
240    * @since 10.0
241    */
242   @Beta
243   protected class StandardElementSet extends Multisets.ElementSet<E> {
244     /** Constructor for use by subclasses. */
StandardElementSet()245     public StandardElementSet() {}
246 
247     @Override
multiset()248     Multiset<E> multiset() {
249       return ForwardingMultiset.this;
250     }
251   }
252 
253   /**
254    * A sensible definition of {@link #iterator} in terms of {@link #entrySet}
255    * and {@link #remove(Object)}. If you override either of these methods, you
256    * may wish to override {@link #iterator} to forward to this implementation.
257    *
258    * @since 7.0
259    */
standardIterator()260   protected Iterator<E> standardIterator() {
261     return Multisets.iteratorImpl(this);
262   }
263 
264   /**
265    * A sensible, albeit inefficient, definition of {@link #size} in terms of
266    * {@link #entrySet}. If you override {@link #entrySet}, you may wish to
267    * override {@link #size} to forward to this implementation.
268    *
269    * @since 7.0
270    */
standardSize()271   protected int standardSize() {
272     return Multisets.sizeImpl(this);
273   }
274 
275   /**
276    * A sensible, albeit inefficient, definition of {@link #size} in terms of
277    * {@code entrySet().size()} and {@link #count}. If you override either of
278    * these methods, you may wish to override {@link #size} to forward to this
279    * implementation.
280    *
281    * @since 7.0
282    */
standardEquals(@ullable Object object)283   protected boolean standardEquals(@Nullable Object object) {
284     return Multisets.equalsImpl(this, object);
285   }
286 
287   /**
288    * A sensible definition of {@link #hashCode} as {@code entrySet().hashCode()}
289    * . If you override {@link #entrySet}, you may wish to override {@link
290    * #hashCode} to forward to this implementation.
291    *
292    * @since 7.0
293    */
standardHashCode()294   protected int standardHashCode() {
295     return entrySet().hashCode();
296   }
297 
298   /**
299    * A sensible definition of {@link #toString} as {@code entrySet().toString()}
300    * . If you override {@link #entrySet}, you may wish to override {@link
301    * #toString} to forward to this implementation.
302    *
303    * @since 7.0
304    */
standardToString()305   @Override protected String standardToString() {
306     return entrySet().toString();
307   }
308 }
309