View Javadoc
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. */
56    protected ForwardingMultiset() {}
57  
58    @Override protected abstract Multiset<E> delegate();
59  
60    @Override
61    public int count(Object element) {
62      return delegate().count(element);
63    }
64  
65    @Override
66    public int add(E element, int occurrences) {
67      return delegate().add(element, occurrences);
68    }
69  
70    @Override
71    public int remove(Object element, int occurrences) {
72      return delegate().remove(element, occurrences);
73    }
74  
75    @Override
76    public Set<E> elementSet() {
77      return delegate().elementSet();
78    }
79  
80    @Override
81    public Set<Entry<E>> entrySet() {
82      return delegate().entrySet();
83    }
84  
85    @Override public boolean equals(@Nullable Object object) {
86      return object == this || delegate().equals(object);
87    }
88  
89    @Override public int hashCode() {
90      return delegate().hashCode();
91    }
92  
93    @Override
94    public int setCount(E element, int count) {
95      return delegate().setCount(element, count);
96    }
97  
98    @Override
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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    */
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. */
245     public StandardElementSet() {}
246 
247     @Override
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    */
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    */
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    */
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    */
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    */
305   @Override protected String standardToString() {
306     return entrySet().toString();
307   }
308 }