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