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