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.Map; 026import java.util.Set; 027import javax.annotation.Nullable; 028 029/** 030 * A map which forwards all its method calls to another map. Subclasses should 031 * override one or more methods to modify the behavior of the backing map as 032 * 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 ForwardingMap} forward 036 * <i>indiscriminately</i> to the methods of the delegate. For example, 037 * overriding {@link #put} alone <i>will not</i> change the behavior of {@link 038 * #putAll}, which can lead to unexpected behavior. In this case, you should 039 * override {@code putAll} as well, either providing your own implementation, or 040 * delegating to the provided {@code standardPutAll} 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 ForwardingMap}. 045 * 046 * <p>Each of the {@code standard} methods, where appropriate, use {@link 047 * Objects#equal} to test equality for both keys and values. This may not be 048 * the desired behavior for map implementations that use non-standard notions of 049 * key equality, such as a {@code SortedMap} whose comparator is not consistent 050 * with {@code equals}. 051 * 052 * <p>The {@code standard} methods and the collection views they return are not 053 * guaranteed to be thread-safe, even when all of the methods that they depend 054 * on are thread-safe. 055 * 056 * @author Kevin Bourrillion 057 * @author Jared Levy 058 * @author Louis Wasserman 059 * @since 2.0 060 */ 061@GwtCompatible 062public abstract class ForwardingMap<K, V> extends ForwardingObject implements Map<K, V> { 063 // TODO(lowasser): identify places where thread safety is actually lost 064 065 /** Constructor for use by subclasses. */ 066 protected ForwardingMap() {} 067 068 @Override 069 protected abstract Map<K, V> delegate(); 070 071 @Override 072 public int size() { 073 return delegate().size(); 074 } 075 076 @Override 077 public boolean isEmpty() { 078 return delegate().isEmpty(); 079 } 080 081 @CanIgnoreReturnValue 082 @Override 083 public V remove(Object object) { 084 return delegate().remove(object); 085 } 086 087 @Override 088 public void clear() { 089 delegate().clear(); 090 } 091 092 @Override 093 public boolean containsKey(@Nullable Object key) { 094 return delegate().containsKey(key); 095 } 096 097 @Override 098 public boolean containsValue(@Nullable Object value) { 099 return delegate().containsValue(value); 100 } 101 102 @Override 103 public V get(@Nullable Object key) { 104 return delegate().get(key); 105 } 106 107 @CanIgnoreReturnValue 108 @Override 109 public V put(K key, V value) { 110 return delegate().put(key, value); 111 } 112 113 @Override 114 public void putAll(Map<? extends K, ? extends V> map) { 115 delegate().putAll(map); 116 } 117 118 @Override 119 public Set<K> keySet() { 120 return delegate().keySet(); 121 } 122 123 @Override 124 public Collection<V> values() { 125 return delegate().values(); 126 } 127 128 @Override 129 public Set<Entry<K, V>> entrySet() { 130 return delegate().entrySet(); 131 } 132 133 @Override 134 public boolean equals(@Nullable Object object) { 135 return object == this || delegate().equals(object); 136 } 137 138 @Override 139 public int hashCode() { 140 return delegate().hashCode(); 141 } 142 143 /** 144 * A sensible definition of {@link #putAll(Map)} in terms of {@link 145 * #put(Object, Object)}. If you override {@link #put(Object, Object)}, you 146 * may wish to override {@link #putAll(Map)} to forward to this 147 * implementation. 148 * 149 * @since 7.0 150 */ 151 protected void standardPutAll(Map<? extends K, ? extends V> map) { 152 Maps.putAllImpl(this, map); 153 } 154 155 /** 156 * A sensible, albeit inefficient, definition of {@link #remove} in terms of 157 * the {@code iterator} method of {@link #entrySet}. If you override {@link 158 * #entrySet}, you may wish to override {@link #remove} to forward to this 159 * implementation. 160 * 161 * <p>Alternately, you may wish to override {@link #remove} with {@code 162 * keySet().remove}, assuming that approach would not lead to an infinite 163 * loop. 164 * 165 * @since 7.0 166 */ 167 @Beta 168 protected V standardRemove(@Nullable Object key) { 169 Iterator<Entry<K, V>> entryIterator = entrySet().iterator(); 170 while (entryIterator.hasNext()) { 171 Entry<K, V> entry = entryIterator.next(); 172 if (Objects.equal(entry.getKey(), key)) { 173 V value = entry.getValue(); 174 entryIterator.remove(); 175 return value; 176 } 177 } 178 return null; 179 } 180 181 /** 182 * A sensible definition of {@link #clear} in terms of the {@code iterator} 183 * method of {@link #entrySet}. In many cases, you may wish to override 184 * {@link #clear} to forward to this implementation. 185 * 186 * @since 7.0 187 */ 188 protected void standardClear() { 189 Iterators.clear(entrySet().iterator()); 190 } 191 192 /** 193 * A sensible implementation of {@link Map#keySet} in terms of the following 194 * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey}, 195 * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#remove}, {@link 196 * ForwardingMap#size}, and the {@link Set#iterator} method of {@link 197 * ForwardingMap#entrySet}. In many cases, you may wish to override {@link 198 * ForwardingMap#keySet} to forward to this implementation or a subclass 199 * thereof. 200 * 201 * @since 10.0 202 */ 203 @Beta 204 protected class StandardKeySet extends Maps.KeySet<K, V> { 205 /** Constructor for use by subclasses. */ 206 public StandardKeySet() { 207 super(ForwardingMap.this); 208 } 209 } 210 211 /** 212 * A sensible, albeit inefficient, definition of {@link #containsKey} in terms 213 * of the {@code iterator} method of {@link #entrySet}. If you override {@link 214 * #entrySet}, you may wish to override {@link #containsKey} to forward to 215 * this implementation. 216 * 217 * @since 7.0 218 */ 219 @Beta 220 protected boolean standardContainsKey(@Nullable Object key) { 221 return Maps.containsKeyImpl(this, key); 222 } 223 224 /** 225 * A sensible implementation of {@link Map#values} in terms of the following 226 * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsValue}, 227 * {@link ForwardingMap#isEmpty}, {@link ForwardingMap#size}, and the {@link 228 * Set#iterator} method of {@link ForwardingMap#entrySet}. In many cases, you 229 * may wish to override {@link ForwardingMap#values} to forward to this 230 * implementation or a subclass thereof. 231 * 232 * @since 10.0 233 */ 234 @Beta 235 protected class StandardValues extends Maps.Values<K, V> { 236 /** Constructor for use by subclasses. */ 237 public StandardValues() { 238 super(ForwardingMap.this); 239 } 240 } 241 242 /** 243 * A sensible definition of {@link #containsValue} in terms of the {@code 244 * iterator} method of {@link #entrySet}. If you override {@link #entrySet}, 245 * you may wish to override {@link #containsValue} to forward to this 246 * implementation. 247 * 248 * @since 7.0 249 */ 250 protected boolean standardContainsValue(@Nullable Object value) { 251 return Maps.containsValueImpl(this, value); 252 } 253 254 /** 255 * A sensible implementation of {@link Map#entrySet} in terms of the following 256 * methods: {@link ForwardingMap#clear}, {@link ForwardingMap#containsKey}, 257 * {@link ForwardingMap#get}, {@link ForwardingMap#isEmpty}, {@link 258 * ForwardingMap#remove}, and {@link ForwardingMap#size}. In many cases, you 259 * may wish to override {@link #entrySet} to forward to this implementation 260 * or a subclass thereof. 261 * 262 * @since 10.0 263 */ 264 @Beta 265 protected abstract class StandardEntrySet extends Maps.EntrySet<K, V> { 266 /** Constructor for use by subclasses. */ 267 public StandardEntrySet() {} 268 269 @Override 270 Map<K, V> map() { 271 return ForwardingMap.this; 272 } 273 } 274 275 /** 276 * A sensible definition of {@link #isEmpty} in terms of the {@code iterator} 277 * method of {@link #entrySet}. If you override {@link #entrySet}, you may 278 * wish to override {@link #isEmpty} to forward to this implementation. 279 * 280 * @since 7.0 281 */ 282 protected boolean standardIsEmpty() { 283 return !entrySet().iterator().hasNext(); 284 } 285 286 /** 287 * A sensible definition of {@link #equals} in terms of the {@code equals} 288 * method of {@link #entrySet}. If you override {@link #entrySet}, you may 289 * wish to override {@link #equals} to forward to this implementation. 290 * 291 * @since 7.0 292 */ 293 protected boolean standardEquals(@Nullable Object object) { 294 return Maps.equalsImpl(this, object); 295 } 296 297 /** 298 * A sensible definition of {@link #hashCode} in terms of the {@code iterator} 299 * method of {@link #entrySet}. If you override {@link #entrySet}, you may 300 * wish to override {@link #hashCode} to forward to this implementation. 301 * 302 * @since 7.0 303 */ 304 protected int standardHashCode() { 305 return Sets.hashCodeImpl(entrySet()); 306 } 307 308 /** 309 * A sensible definition of {@link #toString} in terms of the {@code iterator} 310 * method of {@link #entrySet}. If you override {@link #entrySet}, you may 311 * wish to override {@link #toString} to forward to this implementation. 312 * 313 * @since 7.0 314 */ 315 protected String standardToString() { 316 return Maps.toStringImpl(this); 317 } 318}