1 /*
2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.util;
27 
28 import jdk.internal.util.ArraysSupport;
29 
30 /**
31  * This class provides a skeletal implementation of the {@code Collection}
32  * interface, to minimize the effort required to implement this interface. <p>
33  *
34  * To implement an unmodifiable collection, the programmer needs only to
35  * extend this class and provide implementations for the {@code iterator} and
36  * {@code size} methods.  (The iterator returned by the {@code iterator}
37  * method must implement {@code hasNext} and {@code next}.)<p>
38  *
39  * To implement a modifiable collection, the programmer must additionally
40  * override this class's {@code add} method (which otherwise throws an
41  * {@code UnsupportedOperationException}), and the iterator returned by the
42  * {@code iterator} method must additionally implement its {@code remove}
43  * method.<p>
44  *
45  * The programmer should generally provide a void (no argument) and
46  * {@code Collection} constructor, as per the recommendation in the
47  * {@code Collection} interface specification.<p>
48  *
49  * The documentation for each non-abstract method in this class describes its
50  * implementation in detail.  Each of these methods may be overridden if
51  * the collection being implemented admits a more efficient implementation.<p>
52  *
53  * This class is a member of the
54  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
55  * Java Collections Framework</a>.
56  *
57  * @author  Josh Bloch
58  * @author  Neal Gafter
59  * @see Collection
60  * @since 1.2
61  */
62 
63 public abstract class AbstractCollection<E> implements Collection<E> {
64     /**
65      * Sole constructor.  (For invocation by subclass constructors, typically
66      * implicit.)
67      */
AbstractCollection()68     protected AbstractCollection() {
69     }
70 
71     // Query Operations
72 
73     /**
74      * Returns an iterator over the elements contained in this collection.
75      *
76      * @return an iterator over the elements contained in this collection
77      */
iterator()78     public abstract Iterator<E> iterator();
79 
size()80     public abstract int size();
81 
82     /**
83      * {@inheritDoc}
84      *
85      * @implSpec
86      * This implementation returns {@code size() == 0}.
87      */
isEmpty()88     public boolean isEmpty() {
89         return size() == 0;
90     }
91 
92     /**
93      * {@inheritDoc}
94      *
95      * @implSpec
96      * This implementation iterates over the elements in the collection,
97      * checking each element in turn for equality with the specified element.
98      *
99      * @throws ClassCastException   {@inheritDoc}
100      * @throws NullPointerException {@inheritDoc}
101      */
contains(Object o)102     public boolean contains(Object o) {
103         Iterator<E> it = iterator();
104         if (o==null) {
105             while (it.hasNext())
106                 if (it.next()==null)
107                     return true;
108         } else {
109             while (it.hasNext())
110                 if (o.equals(it.next()))
111                     return true;
112         }
113         return false;
114     }
115 
116     /**
117      * {@inheritDoc}
118      *
119      * @implSpec
120      * This implementation returns an array containing all the elements
121      * returned by this collection's iterator, in the same order, stored in
122      * consecutive elements of the array, starting with index {@code 0}.
123      * The length of the returned array is equal to the number of elements
124      * returned by the iterator, even if the size of this collection changes
125      * during iteration, as might happen if the collection permits
126      * concurrent modification during iteration.  The {@code size} method is
127      * called only as an optimization hint; the correct result is returned
128      * even if the iterator returns a different number of elements.
129      *
130      * <p>This method is equivalent to:
131      *
132      *  <pre> {@code
133      * List<E> list = new ArrayList<E>(size());
134      * for (E e : this)
135      *     list.add(e);
136      * return list.toArray();
137      * }</pre>
138      */
toArray()139     public Object[] toArray() {
140         // Estimate size of array; be prepared to see more or fewer elements
141         Object[] r = new Object[size()];
142         Iterator<E> it = iterator();
143         for (int i = 0; i < r.length; i++) {
144             if (! it.hasNext()) // fewer elements than expected
145                 return Arrays.copyOf(r, i);
146             r[i] = it.next();
147         }
148         return it.hasNext() ? finishToArray(r, it) : r;
149     }
150 
151     /**
152      * {@inheritDoc}
153      *
154      * @implSpec
155      * This implementation returns an array containing all the elements
156      * returned by this collection's iterator in the same order, stored in
157      * consecutive elements of the array, starting with index {@code 0}.
158      * If the number of elements returned by the iterator is too large to
159      * fit into the specified array, then the elements are returned in a
160      * newly allocated array with length equal to the number of elements
161      * returned by the iterator, even if the size of this collection
162      * changes during iteration, as might happen if the collection permits
163      * concurrent modification during iteration.  The {@code size} method is
164      * called only as an optimization hint; the correct result is returned
165      * even if the iterator returns a different number of elements.
166      *
167      * <p>This method is equivalent to:
168      *
169      *  <pre> {@code
170      * List<E> list = new ArrayList<E>(size());
171      * for (E e : this)
172      *     list.add(e);
173      * return list.toArray(a);
174      * }</pre>
175      *
176      * @throws ArrayStoreException  {@inheritDoc}
177      * @throws NullPointerException {@inheritDoc}
178      */
179     @SuppressWarnings("unchecked")
toArray(T[] a)180     public <T> T[] toArray(T[] a) {
181         // Estimate size of array; be prepared to see more or fewer elements
182         int size = size();
183         T[] r = a.length >= size ? a :
184                   (T[])java.lang.reflect.Array
185                   .newInstance(a.getClass().getComponentType(), size);
186         Iterator<E> it = iterator();
187 
188         for (int i = 0; i < r.length; i++) {
189             if (! it.hasNext()) { // fewer elements than expected
190                 if (a == r) {
191                     r[i] = null; // null-terminate
192                 } else if (a.length < i) {
193                     return Arrays.copyOf(r, i);
194                 } else {
195                     System.arraycopy(r, 0, a, 0, i);
196                     if (a.length > i) {
197                         a[i] = null;
198                     }
199                 }
200                 return a;
201             }
202             r[i] = (T)it.next();
203         }
204         // more elements than expected
205         return it.hasNext() ? finishToArray(r, it) : r;
206     }
207 
208     /**
209      * Reallocates the array being used within toArray when the iterator
210      * returned more elements than expected, and finishes filling it from
211      * the iterator.
212      *
213      * @param r the array, replete with previously stored elements
214      * @param it the in-progress iterator over this collection
215      * @return array containing the elements in the given array, plus any
216      *         further elements returned by the iterator, trimmed to size
217      */
218     @SuppressWarnings("unchecked")
finishToArray(T[] r, Iterator<?> it)219     private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
220         int len = r.length;
221         int i = len;
222         while (it.hasNext()) {
223             if (i == len) {
224                 len = ArraysSupport.newLength(len,
225                         1,             /* minimum growth */
226                         (len >> 1) + 1 /* preferred growth */);
227                 r = Arrays.copyOf(r, len);
228             }
229             r[i++] = (T)it.next();
230         }
231         // trim if overallocated
232         return (i == len) ? r : Arrays.copyOf(r, i);
233     }
234 
235     // Modification Operations
236 
237     /**
238      * {@inheritDoc}
239      *
240      * @implSpec
241      * This implementation always throws an
242      * {@code UnsupportedOperationException}.
243      *
244      * @throws UnsupportedOperationException {@inheritDoc}
245      * @throws ClassCastException            {@inheritDoc}
246      * @throws NullPointerException          {@inheritDoc}
247      * @throws IllegalArgumentException      {@inheritDoc}
248      * @throws IllegalStateException         {@inheritDoc}
249      */
add(E e)250     public boolean add(E e) {
251         throw new UnsupportedOperationException();
252     }
253 
254     /**
255      * {@inheritDoc}
256      *
257      * @implSpec
258      * This implementation iterates over the collection looking for the
259      * specified element.  If it finds the element, it removes the element
260      * from the collection using the iterator's remove method.
261      *
262      * <p>Note that this implementation throws an
263      * {@code UnsupportedOperationException} if the iterator returned by this
264      * collection's iterator method does not implement the {@code remove}
265      * method and this collection contains the specified object.
266      *
267      * @throws UnsupportedOperationException {@inheritDoc}
268      * @throws ClassCastException            {@inheritDoc}
269      * @throws NullPointerException          {@inheritDoc}
270      */
remove(Object o)271     public boolean remove(Object o) {
272         Iterator<E> it = iterator();
273         if (o==null) {
274             while (it.hasNext()) {
275                 if (it.next()==null) {
276                     it.remove();
277                     return true;
278                 }
279             }
280         } else {
281             while (it.hasNext()) {
282                 if (o.equals(it.next())) {
283                     it.remove();
284                     return true;
285                 }
286             }
287         }
288         return false;
289     }
290 
291 
292     // Bulk Operations
293 
294     /**
295      * {@inheritDoc}
296      *
297      * @implSpec
298      * This implementation iterates over the specified collection,
299      * checking each element returned by the iterator in turn to see
300      * if it's contained in this collection.  If all elements are so
301      * contained {@code true} is returned, otherwise {@code false}.
302      *
303      * @throws ClassCastException            {@inheritDoc}
304      * @throws NullPointerException          {@inheritDoc}
305      * @see #contains(Object)
306      */
containsAll(Collection<?> c)307     public boolean containsAll(Collection<?> c) {
308         for (Object e : c)
309             if (!contains(e))
310                 return false;
311         return true;
312     }
313 
314     /**
315      * {@inheritDoc}
316      *
317      * @implSpec
318      * This implementation iterates over the specified collection, and adds
319      * each object returned by the iterator to this collection, in turn.
320      *
321      * <p>Note that this implementation will throw an
322      * {@code UnsupportedOperationException} unless {@code add} is
323      * overridden (assuming the specified collection is non-empty).
324      *
325      * @throws UnsupportedOperationException {@inheritDoc}
326      * @throws ClassCastException            {@inheritDoc}
327      * @throws NullPointerException          {@inheritDoc}
328      * @throws IllegalArgumentException      {@inheritDoc}
329      * @throws IllegalStateException         {@inheritDoc}
330      *
331      * @see #add(Object)
332      */
addAll(Collection<? extends E> c)333     public boolean addAll(Collection<? extends E> c) {
334         boolean modified = false;
335         for (E e : c)
336             if (add(e))
337                 modified = true;
338         return modified;
339     }
340 
341     /**
342      * {@inheritDoc}
343      *
344      * @implSpec
345      * This implementation iterates over this collection, checking each
346      * element returned by the iterator in turn to see if it's contained
347      * in the specified collection.  If it's so contained, it's removed from
348      * this collection with the iterator's {@code remove} method.
349      *
350      * <p>Note that this implementation will throw an
351      * {@code UnsupportedOperationException} if the iterator returned by the
352      * {@code iterator} method does not implement the {@code remove} method
353      * and this collection contains one or more elements in common with the
354      * specified collection.
355      *
356      * @throws UnsupportedOperationException {@inheritDoc}
357      * @throws ClassCastException            {@inheritDoc}
358      * @throws NullPointerException          {@inheritDoc}
359      *
360      * @see #remove(Object)
361      * @see #contains(Object)
362      */
removeAll(Collection<?> c)363     public boolean removeAll(Collection<?> c) {
364         Objects.requireNonNull(c);
365         boolean modified = false;
366         Iterator<?> it = iterator();
367         while (it.hasNext()) {
368             if (c.contains(it.next())) {
369                 it.remove();
370                 modified = true;
371             }
372         }
373         return modified;
374     }
375 
376     /**
377      * {@inheritDoc}
378      *
379      * @implSpec
380      * This implementation iterates over this collection, checking each
381      * element returned by the iterator in turn to see if it's contained
382      * in the specified collection.  If it's not so contained, it's removed
383      * from this collection with the iterator's {@code remove} method.
384      *
385      * <p>Note that this implementation will throw an
386      * {@code UnsupportedOperationException} if the iterator returned by the
387      * {@code iterator} method does not implement the {@code remove} method
388      * and this collection contains one or more elements not present in the
389      * specified collection.
390      *
391      * @throws UnsupportedOperationException {@inheritDoc}
392      * @throws ClassCastException            {@inheritDoc}
393      * @throws NullPointerException          {@inheritDoc}
394      *
395      * @see #remove(Object)
396      * @see #contains(Object)
397      */
retainAll(Collection<?> c)398     public boolean retainAll(Collection<?> c) {
399         Objects.requireNonNull(c);
400         boolean modified = false;
401         Iterator<E> it = iterator();
402         while (it.hasNext()) {
403             if (!c.contains(it.next())) {
404                 it.remove();
405                 modified = true;
406             }
407         }
408         return modified;
409     }
410 
411     /**
412      * {@inheritDoc}
413      *
414      * @implSpec
415      * This implementation iterates over this collection, removing each
416      * element using the {@code Iterator.remove} operation.  Most
417      * implementations will probably choose to override this method for
418      * efficiency.
419      *
420      * <p>Note that this implementation will throw an
421      * {@code UnsupportedOperationException} if the iterator returned by this
422      * collection's {@code iterator} method does not implement the
423      * {@code remove} method and this collection is non-empty.
424      *
425      * @throws UnsupportedOperationException {@inheritDoc}
426      */
clear()427     public void clear() {
428         Iterator<E> it = iterator();
429         while (it.hasNext()) {
430             it.next();
431             it.remove();
432         }
433     }
434 
435 
436     //  String conversion
437 
438     /**
439      * Returns a string representation of this collection.  The string
440      * representation consists of a list of the collection's elements in the
441      * order they are returned by its iterator, enclosed in square brackets
442      * ({@code "[]"}).  Adjacent elements are separated by the characters
443      * {@code ", "} (comma and space).  Elements are converted to strings as
444      * by {@link String#valueOf(Object)}.
445      *
446      * @return a string representation of this collection
447      */
toString()448     public String toString() {
449         Iterator<E> it = iterator();
450         if (! it.hasNext())
451             return "[]";
452 
453         StringBuilder sb = new StringBuilder();
454         sb.append('[');
455         for (;;) {
456             E e = it.next();
457             sb.append(e == this ? "(this Collection)" : e);
458             if (! it.hasNext())
459                 return sb.append(']').toString();
460             sb.append(',').append(' ');
461         }
462     }
463 
464 }
465