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 static com.google.common.collect.Collections2.containsAllImpl; 020import static com.google.common.collect.Collections2.toStringImpl; 021 022import com.google.common.annotations.GwtCompatible; 023import com.google.errorprone.annotations.CanIgnoreReturnValue; 024import java.util.Collection; 025import java.util.Iterator; 026import java.util.Objects; 027import org.jspecify.annotations.Nullable; 028 029/** 030 * A collection which forwards all its method calls to another collection. Subclasses should 031 * override one or more methods to modify the behavior of the backing collection as desired per the 032 * <a href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>. 033 * 034 * <p><b>Warning:</b> The methods of {@code ForwardingCollection} forward <b>indiscriminately</b> to 035 * the methods of the delegate. For example, overriding {@link #add} alone <b>will not</b> change 036 * the behavior of {@link #addAll}, which can lead to unexpected behavior. In this case, you should 037 * override {@code addAll} as well, either providing your own implementation, or delegating to the 038 * provided {@code standardAddAll} 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 ForwardingCollection}. 043 * 044 * <p>The {@code standard} methods are not guaranteed to be thread-safe, even when all of the 045 * methods that they depend on are thread-safe. 046 * 047 * @author Kevin Bourrillion 048 * @author Louis Wasserman 049 * @since 2.0 050 */ 051@GwtCompatible 052public abstract class ForwardingCollection<E extends @Nullable Object> extends ForwardingObject 053 implements Collection<E> { 054 // TODO(lowasser): identify places where thread safety is actually lost 055 056 /** Constructor for use by subclasses. */ 057 protected ForwardingCollection() {} 058 059 @Override 060 protected abstract Collection<E> delegate(); 061 062 @Override 063 public Iterator<E> iterator() { 064 return delegate().iterator(); 065 } 066 067 @Override 068 public int size() { 069 return delegate().size(); 070 } 071 072 @CanIgnoreReturnValue 073 @Override 074 public boolean removeAll(Collection<?> collection) { 075 return delegate().removeAll(collection); 076 } 077 078 @Override 079 public boolean isEmpty() { 080 return delegate().isEmpty(); 081 } 082 083 @Override 084 public boolean contains(@Nullable Object object) { 085 return delegate().contains(object); 086 } 087 088 @CanIgnoreReturnValue 089 @Override 090 public boolean add(@ParametricNullness E element) { 091 return delegate().add(element); 092 } 093 094 @CanIgnoreReturnValue 095 @Override 096 public boolean remove(@Nullable Object object) { 097 return delegate().remove(object); 098 } 099 100 @Override 101 public boolean containsAll(Collection<?> collection) { 102 return delegate().containsAll(collection); 103 } 104 105 @CanIgnoreReturnValue 106 @Override 107 public boolean addAll(Collection<? extends E> collection) { 108 return delegate().addAll(collection); 109 } 110 111 @CanIgnoreReturnValue 112 @Override 113 public boolean retainAll(Collection<?> collection) { 114 return delegate().retainAll(collection); 115 } 116 117 @Override 118 public void clear() { 119 delegate().clear(); 120 } 121 122 @Override 123 public @Nullable Object[] toArray() { 124 return delegate().toArray(); 125 } 126 127 @CanIgnoreReturnValue 128 @Override 129 @SuppressWarnings("nullness") // b/192354773 in our checker affects toArray declarations 130 public <T extends @Nullable Object> T[] toArray(T[] array) { 131 return delegate().toArray(array); 132 } 133 134 /** 135 * A sensible definition of {@link #contains} in terms of {@link #iterator}. If you override 136 * {@link #iterator}, you may wish to override {@link #contains} to forward to this 137 * implementation. 138 * 139 * @since 7.0 140 */ 141 protected boolean standardContains(@Nullable Object object) { 142 return Iterators.contains(iterator(), object); 143 } 144 145 /** 146 * A sensible definition of {@link #containsAll} in terms of {@link #contains} . If you override 147 * {@link #contains}, you may wish to override {@link #containsAll} to forward to this 148 * implementation. 149 * 150 * @since 7.0 151 */ 152 protected boolean standardContainsAll(Collection<?> collection) { 153 return containsAllImpl(this, collection); 154 } 155 156 /** 157 * A sensible definition of {@link #addAll} in terms of {@link #add}. If you override {@link 158 * #add}, you may wish to override {@link #addAll} to forward to this implementation. 159 * 160 * @since 7.0 161 */ 162 protected boolean standardAddAll(Collection<? extends E> collection) { 163 return Iterators.addAll(this, collection.iterator()); 164 } 165 166 /** 167 * A sensible definition of {@link #remove} in terms of {@link #iterator}, using the iterator's 168 * {@code remove} method. If you override {@link #iterator}, you may wish to override {@link 169 * #remove} to forward to this implementation. 170 * 171 * @since 7.0 172 */ 173 protected boolean standardRemove(@Nullable Object object) { 174 Iterator<E> iterator = iterator(); 175 while (iterator.hasNext()) { 176 if (Objects.equals(iterator.next(), object)) { 177 iterator.remove(); 178 return true; 179 } 180 } 181 return false; 182 } 183 184 /** 185 * A sensible definition of {@link #removeAll} in terms of {@link #iterator}, using the iterator's 186 * {@code remove} method. If you override {@link #iterator}, you may wish to override {@link 187 * #removeAll} to forward to this implementation. 188 * 189 * @since 7.0 190 */ 191 protected boolean standardRemoveAll(Collection<?> collection) { 192 return Iterators.removeAll(iterator(), collection); 193 } 194 195 /** 196 * A sensible definition of {@link #retainAll} in terms of {@link #iterator}, using the iterator's 197 * {@code remove} method. If you override {@link #iterator}, you may wish to override {@link 198 * #retainAll} to forward to this implementation. 199 * 200 * @since 7.0 201 */ 202 protected boolean standardRetainAll(Collection<?> collection) { 203 return Iterators.retainAll(iterator(), collection); 204 } 205 206 /** 207 * A sensible definition of {@link #clear} in terms of {@link #iterator}, using the iterator's 208 * {@code remove} method. If you override {@link #iterator}, you may wish to override {@link 209 * #clear} to forward to this implementation. 210 * 211 * @since 7.0 212 */ 213 protected void standardClear() { 214 Iterators.clear(iterator()); 215 } 216 217 /** 218 * A sensible definition of {@link #isEmpty} as {@code !iterator().hasNext}. If you override 219 * {@link #isEmpty}, you may wish to override {@link #isEmpty} to forward to this implementation. 220 * Alternately, it may be more efficient to implement {@code isEmpty} as {@code size() == 0}. 221 * 222 * @since 7.0 223 */ 224 protected boolean standardIsEmpty() { 225 return !iterator().hasNext(); 226 } 227 228 /** 229 * A sensible definition of {@link #toString} in terms of {@link #iterator}. If you override 230 * {@link #iterator}, you may wish to override {@link #toString} to forward to this 231 * implementation. 232 * 233 * @since 7.0 234 */ 235 protected String standardToString() { 236 return toStringImpl(this); 237 } 238 239 /** 240 * A sensible definition of {@link #toArray()} in terms of {@link #toArray(Object[])}. If you 241 * override {@link #toArray(Object[])}, you may wish to override {@link #toArray} to forward to 242 * this implementation. 243 * 244 * @since 7.0 245 */ 246 protected @Nullable Object[] standardToArray() { 247 @Nullable Object[] newArray = new @Nullable Object[size()]; 248 return toArray(newArray); 249 } 250 251 /** 252 * A sensible definition of {@link #toArray(Object[])} in terms of {@link #size} and {@link 253 * #iterator}. If you override either of these methods, you may wish to override {@link #toArray} 254 * to forward to this implementation. 255 * 256 * @since 7.0 257 */ 258 protected <T extends @Nullable Object> T[] standardToArray(T[] array) { 259 return ObjectArrays.toArrayImpl(this, array); 260 } 261}