jaroslav@557: /* jaroslav@557: * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved. jaroslav@557: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jaroslav@557: * jaroslav@557: * This code is free software; you can redistribute it and/or modify it jaroslav@557: * under the terms of the GNU General Public License version 2 only, as jaroslav@557: * published by the Free Software Foundation. Oracle designates this jaroslav@557: * particular file as subject to the "Classpath" exception as provided jaroslav@557: * by Oracle in the LICENSE file that accompanied this code. jaroslav@557: * jaroslav@557: * This code is distributed in the hope that it will be useful, but WITHOUT jaroslav@557: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jaroslav@557: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jaroslav@557: * version 2 for more details (a copy is included in the LICENSE file that jaroslav@557: * accompanied this code). jaroslav@557: * jaroslav@557: * You should have received a copy of the GNU General Public License version jaroslav@557: * 2 along with this work; if not, write to the Free Software Foundation, jaroslav@557: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jaroslav@557: * jaroslav@557: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jaroslav@557: * or visit www.oracle.com if you need additional information or have any jaroslav@557: * questions. jaroslav@557: */ jaroslav@557: jaroslav@557: package java.util; jaroslav@557: jaroslav@557: /** jaroslav@557: * This class provides a skeletal implementation of the Set jaroslav@557: * interface to minimize the effort required to implement this jaroslav@557: * interface.

jaroslav@557: * jaroslav@557: * The process of implementing a set by extending this class is identical jaroslav@557: * to that of implementing a Collection by extending AbstractCollection, jaroslav@557: * except that all of the methods and constructors in subclasses of this jaroslav@557: * class must obey the additional constraints imposed by the Set jaroslav@557: * interface (for instance, the add method must not permit addition of jaroslav@557: * multiple instances of an object to a set).

jaroslav@557: * jaroslav@557: * Note that this class does not override any of the implementations from jaroslav@557: * the AbstractCollection class. It merely adds implementations jaroslav@557: * for equals and hashCode.

jaroslav@557: * jaroslav@557: * This class is a member of the jaroslav@557: * jaroslav@557: * Java Collections Framework. jaroslav@557: * jaroslav@557: * @param the type of elements maintained by this set jaroslav@557: * jaroslav@557: * @author Josh Bloch jaroslav@557: * @author Neal Gafter jaroslav@557: * @see Collection jaroslav@557: * @see AbstractCollection jaroslav@557: * @see Set jaroslav@557: * @since 1.2 jaroslav@557: */ jaroslav@557: jaroslav@557: public abstract class AbstractSet extends AbstractCollection implements Set { jaroslav@557: /** jaroslav@557: * Sole constructor. (For invocation by subclass constructors, typically jaroslav@557: * implicit.) jaroslav@557: */ jaroslav@557: protected AbstractSet() { jaroslav@557: } jaroslav@557: jaroslav@557: // Comparison and hashing jaroslav@557: jaroslav@557: /** jaroslav@557: * Compares the specified object with this set for equality. Returns jaroslav@557: * true if the given object is also a set, the two sets have jaroslav@557: * the same size, and every member of the given set is contained in jaroslav@557: * this set. This ensures that the equals method works jaroslav@557: * properly across different implementations of the Set jaroslav@557: * interface.

jaroslav@557: * jaroslav@557: * This implementation first checks if the specified object is this jaroslav@557: * set; if so it returns true. Then, it checks if the jaroslav@557: * specified object is a set whose size is identical to the size of jaroslav@557: * this set; if not, it returns false. If so, it returns jaroslav@557: * containsAll((Collection) o). jaroslav@557: * jaroslav@557: * @param o object to be compared for equality with this set jaroslav@557: * @return true if the specified object is equal to this set jaroslav@557: */ jaroslav@557: public boolean equals(Object o) { jaroslav@557: if (o == this) jaroslav@557: return true; jaroslav@557: jaroslav@557: if (!(o instanceof Set)) jaroslav@557: return false; jaroslav@557: Collection c = (Collection) o; jaroslav@557: if (c.size() != size()) jaroslav@557: return false; jaroslav@557: try { jaroslav@557: return containsAll(c); jaroslav@557: } catch (ClassCastException unused) { jaroslav@557: return false; jaroslav@557: } catch (NullPointerException unused) { jaroslav@557: return false; jaroslav@557: } jaroslav@557: } jaroslav@557: jaroslav@557: /** jaroslav@557: * Returns the hash code value for this set. The hash code of a set is jaroslav@557: * defined to be the sum of the hash codes of the elements in the set, jaroslav@557: * where the hash code of a null element is defined to be zero. jaroslav@557: * This ensures that s1.equals(s2) implies that jaroslav@557: * s1.hashCode()==s2.hashCode() for any two sets s1 jaroslav@557: * and s2, as required by the general contract of jaroslav@557: * {@link Object#hashCode}. jaroslav@557: * jaroslav@557: *

This implementation iterates over the set, calling the jaroslav@557: * hashCode method on each element in the set, and adding up jaroslav@557: * the results. jaroslav@557: * jaroslav@557: * @return the hash code value for this set jaroslav@557: * @see Object#equals(Object) jaroslav@557: * @see Set#equals(Object) jaroslav@557: */ jaroslav@557: public int hashCode() { jaroslav@557: int h = 0; jaroslav@557: Iterator i = iterator(); jaroslav@557: while (i.hasNext()) { jaroslav@557: E obj = i.next(); jaroslav@557: if (obj != null) jaroslav@557: h += obj.hashCode(); jaroslav@557: } jaroslav@557: return h; jaroslav@557: } jaroslav@557: jaroslav@557: /** jaroslav@557: * Removes from this set all of its elements that are contained in the jaroslav@557: * specified collection (optional operation). If the specified jaroslav@557: * collection is also a set, this operation effectively modifies this jaroslav@557: * set so that its value is the asymmetric set difference of jaroslav@557: * the two sets. jaroslav@557: * jaroslav@557: *

This implementation determines which is the smaller of this set jaroslav@557: * and the specified collection, by invoking the size jaroslav@557: * method on each. If this set has fewer elements, then the jaroslav@557: * implementation iterates over this set, checking each element jaroslav@557: * returned by the iterator in turn to see if it is contained in jaroslav@557: * the specified collection. If it is so contained, it is removed jaroslav@557: * from this set with the iterator's remove method. If jaroslav@557: * the specified collection has fewer elements, then the jaroslav@557: * implementation iterates over the specified collection, removing jaroslav@557: * from this set each element returned by the iterator, using this jaroslav@557: * set's remove method. jaroslav@557: * jaroslav@557: *

Note that this implementation will throw an jaroslav@557: * UnsupportedOperationException if the iterator returned by the jaroslav@557: * iterator method does not implement the remove method. jaroslav@557: * jaroslav@557: * @param c collection containing elements to be removed from this set jaroslav@557: * @return true if this set changed as a result of the call jaroslav@557: * @throws UnsupportedOperationException if the removeAll operation jaroslav@557: * is not supported by this set jaroslav@557: * @throws ClassCastException if the class of an element of this set jaroslav@557: * is incompatible with the specified collection jaroslav@557: * (optional) jaroslav@557: * @throws NullPointerException if this set contains a null element and the jaroslav@557: * specified collection does not permit null elements jaroslav@557: * (optional), jaroslav@557: * or if the specified collection is null jaroslav@557: * @see #remove(Object) jaroslav@557: * @see #contains(Object) jaroslav@557: */ jaroslav@557: public boolean removeAll(Collection c) { jaroslav@557: boolean modified = false; jaroslav@557: jaroslav@557: if (size() > c.size()) { jaroslav@557: for (Iterator i = c.iterator(); i.hasNext(); ) jaroslav@557: modified |= remove(i.next()); jaroslav@557: } else { jaroslav@557: for (Iterator i = iterator(); i.hasNext(); ) { jaroslav@557: if (c.contains(i.next())) { jaroslav@557: i.remove(); jaroslav@557: modified = true; jaroslav@557: } jaroslav@557: } jaroslav@557: } jaroslav@557: return modified; jaroslav@557: } jaroslav@557: jaroslav@557: }