• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Guava Authors
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.common.collect;
18 
19 import com.google.common.annotations.Beta;
20 import com.google.common.annotations.GwtCompatible;
21 import com.google.common.base.Objects;
22 
23 import java.util.Collection;
24 import java.util.Iterator;
25 
26 import javax.annotation.Nullable;
27 
28 /**
29  * A collection which forwards all its method calls to another collection.
30  * Subclasses should override one or more methods to modify the behavior of the
31  * backing collection as desired per the <a
32  * href="http://en.wikipedia.org/wiki/Decorator_pattern">decorator pattern</a>.
33  *
34  * <p><b>Warning:</b> The methods of {@code ForwardingCollection} forward
35  * <b>indiscriminately</b> to the methods of the delegate. For example,
36  * overriding {@link #add} alone <b>will not</b> change the behavior of {@link
37  * #addAll}, which can lead to unexpected behavior. In this case, you should
38  * override {@code addAll} as well, either providing your own implementation, or
39  * delegating to the provided {@code standardAddAll} method.
40  *
41  * <p>The {@code standard} methods are not guaranteed to be thread-safe, even
42  * when all of the methods that they depend on are thread-safe.
43  *
44  * @author Kevin Bourrillion
45  * @author Louis Wasserman
46  * @since 2.0 (imported from Google Collections Library)
47  */
48 @GwtCompatible
49 public abstract class ForwardingCollection<E> extends ForwardingObject
50     implements Collection<E> {
51   // TODO(user): identify places where thread safety is actually lost
52 
53   /** Constructor for use by subclasses. */
ForwardingCollection()54   protected ForwardingCollection() {}
55 
delegate()56   @Override protected abstract Collection<E> delegate();
57 
58   @Override
iterator()59   public Iterator<E> iterator() {
60     return delegate().iterator();
61   }
62 
63   @Override
size()64   public int size() {
65     return delegate().size();
66   }
67 
68   @Override
removeAll(Collection<?> collection)69   public boolean removeAll(Collection<?> collection) {
70     return delegate().removeAll(collection);
71   }
72 
73   @Override
isEmpty()74   public boolean isEmpty() {
75     return delegate().isEmpty();
76   }
77 
78   @Override
contains(Object object)79   public boolean contains(Object object) {
80     return delegate().contains(object);
81   }
82 
83   @Override
add(E element)84   public boolean add(E element) {
85     return delegate().add(element);
86   }
87 
88   @Override
remove(Object object)89   public boolean remove(Object object) {
90     return delegate().remove(object);
91   }
92 
93   @Override
containsAll(Collection<?> collection)94   public boolean containsAll(Collection<?> collection) {
95     return delegate().containsAll(collection);
96   }
97 
98   @Override
addAll(Collection<? extends E> collection)99   public boolean addAll(Collection<? extends E> collection) {
100     return delegate().addAll(collection);
101   }
102 
103   @Override
retainAll(Collection<?> collection)104   public boolean retainAll(Collection<?> collection) {
105     return delegate().retainAll(collection);
106   }
107 
108   @Override
clear()109   public void clear() {
110     delegate().clear();
111   }
112 
113   @Override
toArray()114   public Object[] toArray() {
115     return delegate().toArray();
116   }
117 
118   @Override
toArray(T[] array)119   public <T> T[] toArray(T[] array) {
120     return delegate().toArray(array);
121   }
122 
123   /**
124    * A sensible definition of {@link #contains} in terms of {@link #iterator}.
125    * If you override {@link #iterator}, you may wish to override {@link
126    * #contains} to forward to this implementation.
127    *
128    * @since 7.0
129    */
standardContains(@ullable Object object)130   @Beta protected boolean standardContains(@Nullable Object object) {
131     return Iterators.contains(iterator(), object);
132   }
133 
134   /**
135    * A sensible definition of {@link #containsAll} in terms of {@link #contains}
136    * . If you override {@link #contains}, you may wish to override {@link
137    * #containsAll} to forward to this implementation.
138    *
139    * @since 7.0
140    */
standardContainsAll(Collection<?> collection)141   @Beta protected boolean standardContainsAll(Collection<?> collection) {
142     for (Object o : collection) {
143       if (!contains(o)) {
144         return false;
145       }
146     }
147     return true;
148   }
149 
150   /**
151    * A sensible definition of {@link #addAll} in terms of {@link #add}. If you
152    * override {@link #add}, you may wish to override {@link #addAll} to forward
153    * to this implementation.
154    *
155    * @since 7.0
156    */
standardAddAll(Collection<? extends E> collection)157   @Beta protected boolean standardAddAll(Collection<? extends E> collection) {
158     return Iterators.addAll(this, collection.iterator());
159   }
160 
161   /**
162    * A sensible definition of {@link #remove} in terms of {@link #iterator},
163    * using the iterator's {@code remove} method. If you override {@link
164    * #iterator}, you may wish to override {@link #remove} to forward to this
165    * implementation.
166    *
167    * @since 7.0
168    */
standardRemove(@ullable Object object)169   @Beta protected boolean standardRemove(@Nullable Object object) {
170     Iterator<E> iterator = iterator();
171     while (iterator.hasNext()) {
172       if (Objects.equal(iterator.next(), object)) {
173         iterator.remove();
174         return true;
175       }
176     }
177     return false;
178   }
179 
180   /**
181    * A sensible definition of {@link #removeAll} in terms of {@link #iterator},
182    * using the iterator's {@code remove} method. If you override {@link
183    * #iterator}, you may wish to override {@link #removeAll} to forward to this
184    * implementation.
185    *
186    * @since 7.0
187    */
standardRemoveAll(Collection<?> collection)188   @Beta protected boolean standardRemoveAll(Collection<?> collection) {
189     return Iterators.removeAll(iterator(), collection);
190   }
191 
192   /**
193    * A sensible definition of {@link #retainAll} in terms of {@link #iterator},
194    * using the iterator's {@code remove} method. If you override {@link
195    * #iterator}, you may wish to override {@link #retainAll} to forward to this
196    * implementation.
197    *
198    * @since 7.0
199    */
standardRetainAll(Collection<?> collection)200   @Beta protected boolean standardRetainAll(Collection<?> collection) {
201     return Iterators.retainAll(iterator(), collection);
202   }
203 
204   /**
205    * A sensible definition of {@link #clear} in terms of {@link #iterator},
206    * using the iterator's {@code remove} method. If you override {@link
207    * #iterator}, you may wish to override {@link #clear} to forward to this
208    * implementation.
209    *
210    * @since 7.0
211    */
standardClear()212   @Beta protected void standardClear() {
213     Iterator<E> iterator = iterator();
214     while (iterator.hasNext()) {
215       iterator.next();
216       iterator.remove();
217     }
218   }
219 
220   /**
221    * A sensible definition of {@link #isEmpty} as {@code !iterator().hasNext}.
222    * If you override {@link #isEmpty}, you may wish to override {@link #isEmpty}
223    * to forward to this implementation. Alternately, it may be more efficient to
224    * implement {@code isEmpty} as {@code size() == 0}.
225    *
226    * @since 7.0
227    */
standardIsEmpty()228   @Beta protected boolean standardIsEmpty() {
229     return !iterator().hasNext();
230   }
231 
232   /**
233    * A sensible definition of {@link #toString} in terms of {@link #iterator}.
234    * If you override {@link #iterator}, you may wish to override {@link
235    * #toString} to forward to this implementation.
236    *
237    * @since 7.0
238    */
standardToString()239   @Beta protected String standardToString() {
240     return Collections2.toStringImpl(this);
241   }
242 
243   /**
244    * A sensible definition of {@link #toArray()} in terms of {@link
245    * #toArray(Object[])}. If you override {@link #toArray(Object[])}, you may
246    * wish to override {@link #toArray} to forward to this implementation.
247    *
248    * @since 7.0
249    */
standardToArray()250   @Beta protected Object[] standardToArray() {
251     Object[] newArray = new Object[size()];
252     return toArray(newArray);
253   }
254 
255   /**
256    * A sensible definition of {@link #toArray(Object[])} in terms of {@link
257    * #size} and {@link #iterator}. If you override either of these methods, you
258    * may wish to override {@link #toArray} to forward to this implementation.
259    *
260    * @since 7.0
261    */
standardToArray(T[] array)262   @Beta protected <T> T[] standardToArray(T[] array) {
263     return ObjectArrays.toArrayImpl(this, array);
264   }
265 }
266