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