Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/util/AbstractCollection.java
38829 views
/*1* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.util;2627/**28* This class provides a skeletal implementation of the <tt>Collection</tt>29* interface, to minimize the effort required to implement this interface. <p>30*31* To implement an unmodifiable collection, the programmer needs only to32* extend this class and provide implementations for the <tt>iterator</tt> and33* <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt>34* method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p>35*36* To implement a modifiable collection, the programmer must additionally37* override this class's <tt>add</tt> method (which otherwise throws an38* <tt>UnsupportedOperationException</tt>), and the iterator returned by the39* <tt>iterator</tt> method must additionally implement its <tt>remove</tt>40* method.<p>41*42* The programmer should generally provide a void (no argument) and43* <tt>Collection</tt> constructor, as per the recommendation in the44* <tt>Collection</tt> interface specification.<p>45*46* The documentation for each non-abstract method in this class describes its47* implementation in detail. Each of these methods may be overridden if48* the collection being implemented admits a more efficient implementation.<p>49*50* This class is a member of the51* <a href="{@docRoot}/../technotes/guides/collections/index.html">52* Java Collections Framework</a>.53*54* @author Josh Bloch55* @author Neal Gafter56* @see Collection57* @since 1.258*/5960public abstract class AbstractCollection<E> implements Collection<E> {61/**62* Sole constructor. (For invocation by subclass constructors, typically63* implicit.)64*/65protected AbstractCollection() {66}6768// Query Operations6970/**71* Returns an iterator over the elements contained in this collection.72*73* @return an iterator over the elements contained in this collection74*/75public abstract Iterator<E> iterator();7677public abstract int size();7879/**80* {@inheritDoc}81*82* <p>This implementation returns <tt>size() == 0</tt>.83*/84public boolean isEmpty() {85return size() == 0;86}8788/**89* {@inheritDoc}90*91* <p>This implementation iterates over the elements in the collection,92* checking each element in turn for equality with the specified element.93*94* @throws ClassCastException {@inheritDoc}95* @throws NullPointerException {@inheritDoc}96*/97public boolean contains(Object o) {98Iterator<E> it = iterator();99if (o==null) {100while (it.hasNext())101if (it.next()==null)102return true;103} else {104while (it.hasNext())105if (o.equals(it.next()))106return true;107}108return false;109}110111/**112* {@inheritDoc}113*114* <p>This implementation returns an array containing all the elements115* returned by this collection's iterator, in the same order, stored in116* consecutive elements of the array, starting with index {@code 0}.117* The length of the returned array is equal to the number of elements118* returned by the iterator, even if the size of this collection changes119* during iteration, as might happen if the collection permits120* concurrent modification during iteration. The {@code size} method is121* called only as an optimization hint; the correct result is returned122* even if the iterator returns a different number of elements.123*124* <p>This method is equivalent to:125*126* <pre> {@code127* List<E> list = new ArrayList<E>(size());128* for (E e : this)129* list.add(e);130* return list.toArray();131* }</pre>132*/133public Object[] toArray() {134// Estimate size of array; be prepared to see more or fewer elements135Object[] r = new Object[size()];136Iterator<E> it = iterator();137for (int i = 0; i < r.length; i++) {138if (! it.hasNext()) // fewer elements than expected139return Arrays.copyOf(r, i);140r[i] = it.next();141}142return it.hasNext() ? finishToArray(r, it) : r;143}144145/**146* {@inheritDoc}147*148* <p>This implementation returns an array containing all the elements149* returned by this collection's iterator in the same order, stored in150* consecutive elements of the array, starting with index {@code 0}.151* If the number of elements returned by the iterator is too large to152* fit into the specified array, then the elements are returned in a153* newly allocated array with length equal to the number of elements154* returned by the iterator, even if the size of this collection155* changes during iteration, as might happen if the collection permits156* concurrent modification during iteration. The {@code size} method is157* called only as an optimization hint; the correct result is returned158* even if the iterator returns a different number of elements.159*160* <p>This method is equivalent to:161*162* <pre> {@code163* List<E> list = new ArrayList<E>(size());164* for (E e : this)165* list.add(e);166* return list.toArray(a);167* }</pre>168*169* @throws ArrayStoreException {@inheritDoc}170* @throws NullPointerException {@inheritDoc}171*/172@SuppressWarnings("unchecked")173public <T> T[] toArray(T[] a) {174// Estimate size of array; be prepared to see more or fewer elements175int size = size();176T[] r = a.length >= size ? a :177(T[])java.lang.reflect.Array178.newInstance(a.getClass().getComponentType(), size);179Iterator<E> it = iterator();180181for (int i = 0; i < r.length; i++) {182if (! it.hasNext()) { // fewer elements than expected183if (a == r) {184r[i] = null; // null-terminate185} else if (a.length < i) {186return Arrays.copyOf(r, i);187} else {188System.arraycopy(r, 0, a, 0, i);189if (a.length > i) {190a[i] = null;191}192}193return a;194}195r[i] = (T)it.next();196}197// more elements than expected198return it.hasNext() ? finishToArray(r, it) : r;199}200201/**202* The maximum size of array to allocate.203* Some VMs reserve some header words in an array.204* Attempts to allocate larger arrays may result in205* OutOfMemoryError: Requested array size exceeds VM limit206*/207private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;208209/**210* Reallocates the array being used within toArray when the iterator211* returned more elements than expected, and finishes filling it from212* the iterator.213*214* @param r the array, replete with previously stored elements215* @param it the in-progress iterator over this collection216* @return array containing the elements in the given array, plus any217* further elements returned by the iterator, trimmed to size218*/219@SuppressWarnings("unchecked")220private static <T> T[] finishToArray(T[] r, Iterator<?> it) {221int i = r.length;222while (it.hasNext()) {223int cap = r.length;224if (i == cap) {225int newCap = cap + (cap >> 1) + 1;226// overflow-conscious code227if (newCap - MAX_ARRAY_SIZE > 0)228newCap = hugeCapacity(cap + 1);229r = Arrays.copyOf(r, newCap);230}231r[i++] = (T)it.next();232}233// trim if overallocated234return (i == r.length) ? r : Arrays.copyOf(r, i);235}236237private static int hugeCapacity(int minCapacity) {238if (minCapacity < 0) // overflow239throw new OutOfMemoryError240("Required array size too large");241return (minCapacity > MAX_ARRAY_SIZE) ?242Integer.MAX_VALUE :243MAX_ARRAY_SIZE;244}245246// Modification Operations247248/**249* {@inheritDoc}250*251* <p>This implementation always throws an252* <tt>UnsupportedOperationException</tt>.253*254* @throws UnsupportedOperationException {@inheritDoc}255* @throws ClassCastException {@inheritDoc}256* @throws NullPointerException {@inheritDoc}257* @throws IllegalArgumentException {@inheritDoc}258* @throws IllegalStateException {@inheritDoc}259*/260public boolean add(E e) {261throw new UnsupportedOperationException();262}263264/**265* {@inheritDoc}266*267* <p>This implementation iterates over the collection looking for the268* specified element. If it finds the element, it removes the element269* from the collection using the iterator's remove method.270*271* <p>Note that this implementation throws an272* <tt>UnsupportedOperationException</tt> if the iterator returned by this273* collection's iterator method does not implement the <tt>remove</tt>274* method and this collection contains the specified object.275*276* @throws UnsupportedOperationException {@inheritDoc}277* @throws ClassCastException {@inheritDoc}278* @throws NullPointerException {@inheritDoc}279*/280public boolean remove(Object o) {281Iterator<E> it = iterator();282if (o==null) {283while (it.hasNext()) {284if (it.next()==null) {285it.remove();286return true;287}288}289} else {290while (it.hasNext()) {291if (o.equals(it.next())) {292it.remove();293return true;294}295}296}297return false;298}299300301// Bulk Operations302303/**304* {@inheritDoc}305*306* <p>This implementation iterates over the specified collection,307* checking each element returned by the iterator in turn to see308* if it's contained in this collection. If all elements are so309* contained <tt>true</tt> is returned, otherwise <tt>false</tt>.310*311* @throws ClassCastException {@inheritDoc}312* @throws NullPointerException {@inheritDoc}313* @see #contains(Object)314*/315public boolean containsAll(Collection<?> c) {316for (Object e : c)317if (!contains(e))318return false;319return true;320}321322/**323* {@inheritDoc}324*325* <p>This implementation iterates over the specified collection, and adds326* each object returned by the iterator to this collection, in turn.327*328* <p>Note that this implementation will throw an329* <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is330* overridden (assuming the specified collection is non-empty).331*332* @throws UnsupportedOperationException {@inheritDoc}333* @throws ClassCastException {@inheritDoc}334* @throws NullPointerException {@inheritDoc}335* @throws IllegalArgumentException {@inheritDoc}336* @throws IllegalStateException {@inheritDoc}337*338* @see #add(Object)339*/340public boolean addAll(Collection<? extends E> c) {341boolean modified = false;342for (E e : c)343if (add(e))344modified = true;345return modified;346}347348/**349* {@inheritDoc}350*351* <p>This implementation iterates over this collection, checking each352* element returned by the iterator in turn to see if it's contained353* in the specified collection. If it's so contained, it's removed from354* this collection with the iterator's <tt>remove</tt> method.355*356* <p>Note that this implementation will throw an357* <tt>UnsupportedOperationException</tt> if the iterator returned by the358* <tt>iterator</tt> method does not implement the <tt>remove</tt> method359* and this collection contains one or more elements in common with the360* specified collection.361*362* @throws UnsupportedOperationException {@inheritDoc}363* @throws ClassCastException {@inheritDoc}364* @throws NullPointerException {@inheritDoc}365*366* @see #remove(Object)367* @see #contains(Object)368*/369public boolean removeAll(Collection<?> c) {370Objects.requireNonNull(c);371boolean modified = false;372Iterator<?> it = iterator();373while (it.hasNext()) {374if (c.contains(it.next())) {375it.remove();376modified = true;377}378}379return modified;380}381382/**383* {@inheritDoc}384*385* <p>This implementation iterates over this collection, checking each386* element returned by the iterator in turn to see if it's contained387* in the specified collection. If it's not so contained, it's removed388* from this collection with the iterator's <tt>remove</tt> method.389*390* <p>Note that this implementation will throw an391* <tt>UnsupportedOperationException</tt> if the iterator returned by the392* <tt>iterator</tt> method does not implement the <tt>remove</tt> method393* and this collection contains one or more elements not present in the394* specified collection.395*396* @throws UnsupportedOperationException {@inheritDoc}397* @throws ClassCastException {@inheritDoc}398* @throws NullPointerException {@inheritDoc}399*400* @see #remove(Object)401* @see #contains(Object)402*/403public boolean retainAll(Collection<?> c) {404Objects.requireNonNull(c);405boolean modified = false;406Iterator<E> it = iterator();407while (it.hasNext()) {408if (!c.contains(it.next())) {409it.remove();410modified = true;411}412}413return modified;414}415416/**417* {@inheritDoc}418*419* <p>This implementation iterates over this collection, removing each420* element using the <tt>Iterator.remove</tt> operation. Most421* implementations will probably choose to override this method for422* efficiency.423*424* <p>Note that this implementation will throw an425* <tt>UnsupportedOperationException</tt> if the iterator returned by this426* collection's <tt>iterator</tt> method does not implement the427* <tt>remove</tt> method and this collection is non-empty.428*429* @throws UnsupportedOperationException {@inheritDoc}430*/431public void clear() {432Iterator<E> it = iterator();433while (it.hasNext()) {434it.next();435it.remove();436}437}438439440// String conversion441442/**443* Returns a string representation of this collection. The string444* representation consists of a list of the collection's elements in the445* order they are returned by its iterator, enclosed in square brackets446* (<tt>"[]"</tt>). Adjacent elements are separated by the characters447* <tt>", "</tt> (comma and space). Elements are converted to strings as448* by {@link String#valueOf(Object)}.449*450* @return a string representation of this collection451*/452public String toString() {453Iterator<E> it = iterator();454if (! it.hasNext())455return "[]";456457StringBuilder sb = new StringBuilder();458sb.append('[');459for (;;) {460E e = it.next();461sb.append(e == this ? "(this Collection)" : e);462if (! it.hasNext())463return sb.append(']').toString();464sb.append(',').append(' ');465}466}467468}469470471