001 /* 002 * Copyright (C) 2007 Google Inc. 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 (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 @Override protected abstract Multiset<E> delegate(); 059 060 public int count(Object element) { 061 return delegate().count(element); 062 } 063 064 public int add(E element, int occurrences) { 065 return delegate().add(element, occurrences); 066 } 067 068 public int remove(Object element, int occurrences) { 069 return delegate().remove(element, occurrences); 070 } 071 072 public Set<E> elementSet() { 073 return delegate().elementSet(); 074 } 075 076 public Set<Entry<E>> entrySet() { 077 return delegate().entrySet(); 078 } 079 080 @Override public boolean equals(@Nullable Object object) { 081 return object == this || delegate().equals(object); 082 } 083 084 @Override public int hashCode() { 085 return delegate().hashCode(); 086 } 087 088 public int setCount(E element, int count) { 089 return delegate().setCount(element, count); 090 } 091 092 public boolean setCount(E element, int oldCount, int newCount) { 093 return delegate().setCount(element, oldCount, newCount); 094 } 095 096 /** 097 * A sensible definition of {@link #contains} in terms of {@link #count}. If 098 * you override {@link #count}, you may wish to override {@link #contains} to 099 * forward to this implementation. 100 * 101 * @since 7 102 */ 103 @Override @Beta protected boolean standardContains(@Nullable Object object) { 104 return count(object) > 0; 105 } 106 107 /** 108 * A sensible definition of {@link #clear} in terms of the {@code iterator} 109 * method of {@link #entrySet}. If you override {@link #entrySet}, you may 110 * wish to override {@link #contains} to forward to this implementation. 111 * 112 * @since 7 113 */ 114 @Override @Beta protected void standardClear() { 115 Iterator<Entry<E>> entryIterator = entrySet().iterator(); 116 while (entryIterator.hasNext()) { 117 entryIterator.next(); 118 entryIterator.remove(); 119 } 120 } 121 122 /** 123 * A sensible, albeit inefficient, definition of {@link #count} in terms of 124 * {@link #entrySet}. If you override {@link #entrySet}, you may wish to 125 * override {@link #count} to forward to this implementation. 126 * 127 * @since 7 128 */ 129 @Beta protected int standardCount(@Nullable Object object) { 130 for (Entry<?> entry : this.entrySet()) { 131 if (Objects.equal(entry.getElement(), object)) { 132 return entry.getCount(); 133 } 134 } 135 return 0; 136 } 137 138 /** 139 * A sensible definition of {@link #add(Object)} in terms of {@link 140 * #add(Object, int)}. If you override {@link #add(Object, int)}, you may 141 * wish to override {@link #add(Object)} to forward to this implementation. 142 * 143 * @since 7 144 */ 145 @Beta protected boolean standardAdd(E element) { 146 add(element, 1); 147 return true; 148 } 149 150 /** 151 * A sensible definition of {@link #addAll(Collection)} in terms of {@link 152 * #add(Object)} and {@link #add(Object, int)}. If you override either of 153 * these methods, you may wish to override {@link #addAll(Collection)} to 154 * forward to this implementation. 155 * 156 * @since 7 157 */ 158 @Beta @Override protected boolean standardAddAll( 159 Collection<? extends E> elementsToAdd) { 160 return Multisets.addAllImpl(this, elementsToAdd); 161 } 162 163 /** 164 * A sensible definition of {@link #remove(Object)} in terms of {@link 165 * #remove(Object, int)}. If you override {@link #remove(Object, int)}, you 166 * may wish to override {@link #remove(Object)} to forward to this 167 * implementation. 168 * 169 * @since 7 170 */ 171 @Beta @Override protected boolean standardRemove(Object element) { 172 return remove(element, 1) > 0; 173 } 174 175 /** 176 * A sensible definition of {@link #removeAll} in terms of the {@code 177 * removeAll} method of {@link #elementSet}. If you override {@link 178 * #elementSet}, you may wish to override {@link #removeAll} to forward to 179 * this implementation. 180 * 181 * @since 7 182 */ 183 @Beta @Override protected boolean standardRemoveAll( 184 Collection<?> elementsToRemove) { 185 return Multisets.removeAllImpl(this, elementsToRemove); 186 } 187 188 /** 189 * A sensible definition of {@link #retainAll} in terms of the {@code 190 * retainAll} method of {@link #elementSet}. If you override {@link 191 * #elementSet}, you may wish to override {@link #retainAll} to forward to 192 * this implementation. 193 * 194 * @since 7 195 */ 196 @Beta @Override protected boolean standardRetainAll( 197 Collection<?> elementsToRetain) { 198 return Multisets.retainAllImpl(this, elementsToRetain); 199 } 200 201 /** 202 * A sensible definition of {@link #setCount(Object, int)} in terms of {@link 203 * #count(Object)}, {@link #add(Object, int)}, and {@link #remove(Object, 204 * int)}. {@link #entrySet()}. If you override any of these methods, you may 205 * wish to override {@link #setCount(Object, int)} to forward to this 206 * implementation. 207 * 208 * @since 7 209 */ 210 @Beta protected int standardSetCount(E element, int count) { 211 return Multisets.setCountImpl(this, element, count); 212 } 213 214 /** 215 * A sensible definition of {@link #setCount(Object, int, int)} in terms of 216 * {@link #count(Object)} and {@link #setCount(Object, int)}. If you override 217 * either of these methods, you may wish to override {@link #setCount(Object, 218 * int, int)} to forward to this implementation. 219 * 220 * @since 7 221 */ 222 @Beta protected boolean standardSetCount( 223 E element, int oldCount, int newCount) { 224 return Multisets.setCountImpl(this, element, oldCount, newCount); 225 } 226 227 /** 228 * A sensible definition of {@link #elementSet} in terms of the following 229 * methods: {@link #clear}, {@link #contains}, {@link #containsAll}, 230 * {@link #count}, {@link #isEmpty}, the {@code size()} and {@code iterator()} 231 * methods of {@link #entrySet}, and {@link #remove(Object, int)}. In many 232 * situations, you may wish to override {@link #elementSet} to forward to this 233 * implementation. 234 * 235 * @since 7 236 */ 237 @Beta protected Set<E> standardElementSet() { 238 return Multisets.elementSetImpl(this); 239 } 240 241 /** 242 * A sensible definition of {@link #iterator} in terms of {@link #entrySet} 243 * and {@link #remove(Object)}. If you override either of these methods, you 244 * may wish to override {@link #iterator} to forward to this implementation. 245 * 246 * @since 7 247 */ 248 @Beta protected Iterator<E> standardIterator() { 249 return Multisets.iteratorImpl(this); 250 } 251 252 /** 253 * A sensible, albeit inefficient, definition of {@link #size} in terms of 254 * {@link #entrySet}. If you override {@link #entrySet}, you may wish to 255 * override {@link #size} to forward to this implementation. 256 * 257 * @since 7 258 */ 259 @Beta protected int standardSize() { 260 return Multisets.sizeImpl(this); 261 } 262 263 /** 264 * A sensible, albeit inefficient, definition of {@link #size} in terms of 265 * {@code entrySet().size()} and {@link #count}. If you override either of 266 * these methods, you may wish to override {@link #size} to forward to this 267 * implementation. 268 * 269 * @since 7 270 */ 271 @Beta protected boolean standardEquals(@Nullable Object object) { 272 return Multisets.equalsImpl(this, object); 273 } 274 275 /** 276 * A sensible definition of {@link #hashCode} as {@code entrySet().hashCode()} 277 * . If you override {@link #entrySet}, you may wish to override {@link 278 * #hashCode} to forward to this implementation. 279 * 280 * @since 7 281 */ 282 @Beta protected int standardHashCode() { 283 return entrySet().hashCode(); 284 } 285 286 /** 287 * A sensible definition of {@link #toString} as {@code entrySet().toString()} 288 * . If you override {@link #entrySet}, you may wish to override {@link 289 * #toString} to forward to this implementation. 290 * 291 * @since 7 292 */ 293 @Beta @Override protected String standardToString() { 294 return entrySet().toString(); 295 } 296 }