001: /*
002: * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package java.util;
027:
028: /**
029: * This class provides a skeletal implementation of the <tt>Set</tt>
030: * interface to minimize the effort required to implement this
031: * interface. <p>
032: *
033: * The process of implementing a set by extending this class is identical
034: * to that of implementing a Collection by extending AbstractCollection,
035: * except that all of the methods and constructors in subclasses of this
036: * class must obey the additional constraints imposed by the <tt>Set</tt>
037: * interface (for instance, the add method must not permit addition of
038: * multiple instances of an object to a set).<p>
039: *
040: * Note that this class does not override any of the implementations from
041: * the <tt>AbstractCollection</tt> class. It merely adds implementations
042: * for <tt>equals</tt> and <tt>hashCode</tt>.<p>
043: *
044: * This class is a member of the
045: * <a href="{@docRoot}/../technotes/guides/collections/index.html">
046: * Java Collections Framework</a>.
047: *
048: * @param <E> the type of elements maintained by this set
049: *
050: * @author Josh Bloch
051: * @author Neal Gafter
052: * @version 1.35, 05/05/07
053: * @see Collection
054: * @see AbstractCollection
055: * @see Set
056: * @since 1.2
057: */
058:
059: public abstract class AbstractSet<E> extends AbstractCollection<E>
060: implements Set<E> {
061: /**
062: * Sole constructor. (For invocation by subclass constructors, typically
063: * implicit.)
064: */
065: protected AbstractSet() {
066: }
067:
068: // Comparison and hashing
069:
070: /**
071: * Compares the specified object with this set for equality. Returns
072: * <tt>true</tt> if the given object is also a set, the two sets have
073: * the same size, and every member of the given set is contained in
074: * this set. This ensures that the <tt>equals</tt> method works
075: * properly across different implementations of the <tt>Set</tt>
076: * interface.<p>
077: *
078: * This implementation first checks if the specified object is this
079: * set; if so it returns <tt>true</tt>. Then, it checks if the
080: * specified object is a set whose size is identical to the size of
081: * this set; if not, it returns false. If so, it returns
082: * <tt>containsAll((Collection) o)</tt>.
083: *
084: * @param o object to be compared for equality with this set
085: * @return <tt>true</tt> if the specified object is equal to this set
086: */
087: public boolean equals(Object o) {
088: if (o == this )
089: return true;
090:
091: if (!(o instanceof Set))
092: return false;
093: Collection c = (Collection) o;
094: if (c.size() != size())
095: return false;
096: try {
097: return containsAll(c);
098: } catch (ClassCastException unused) {
099: return false;
100: } catch (NullPointerException unused) {
101: return false;
102: }
103: }
104:
105: /**
106: * Returns the hash code value for this set. The hash code of a set is
107: * defined to be the sum of the hash codes of the elements in the set,
108: * where the hash code of a <tt>null</tt> element is defined to be zero.
109: * This ensures that <tt>s1.equals(s2)</tt> implies that
110: * <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt>
111: * and <tt>s2</tt>, as required by the general contract of
112: * {@link Object#hashCode}.
113: *
114: * <p>This implementation iterates over the set, calling the
115: * <tt>hashCode</tt> method on each element in the set, and adding up
116: * the results.
117: *
118: * @return the hash code value for this set
119: * @see Object#equals(Object)
120: * @see Set#equals(Object)
121: */
122: public int hashCode() {
123: int h = 0;
124: Iterator<E> i = iterator();
125: while (i.hasNext()) {
126: E obj = i.next();
127: if (obj != null)
128: h += obj.hashCode();
129: }
130: return h;
131: }
132:
133: /**
134: * Removes from this set all of its elements that are contained in the
135: * specified collection (optional operation). If the specified
136: * collection is also a set, this operation effectively modifies this
137: * set so that its value is the <i>asymmetric set difference</i> of
138: * the two sets.
139: *
140: * <p>This implementation determines which is the smaller of this set
141: * and the specified collection, by invoking the <tt>size</tt>
142: * method on each. If this set has fewer elements, then the
143: * implementation iterates over this set, checking each element
144: * returned by the iterator in turn to see if it is contained in
145: * the specified collection. If it is so contained, it is removed
146: * from this set with the iterator's <tt>remove</tt> method. If
147: * the specified collection has fewer elements, then the
148: * implementation iterates over the specified collection, removing
149: * from this set each element returned by the iterator, using this
150: * set's <tt>remove</tt> method.
151: *
152: * <p>Note that this implementation will throw an
153: * <tt>UnsupportedOperationException</tt> if the iterator returned by the
154: * <tt>iterator</tt> method does not implement the <tt>remove</tt> method.
155: *
156: * @param c collection containing elements to be removed from this set
157: * @return <tt>true</tt> if this set changed as a result of the call
158: * @throws UnsupportedOperationException if the <tt>removeAll</tt> operation
159: * is not supported by this set
160: * @throws ClassCastException if the class of an element of this set
161: * is incompatible with the specified collection (optional)
162: * @throws NullPointerException if this set contains a null element and the
163: * specified collection does not permit null elements (optional),
164: * or if the specified collection is null
165: * @see #remove(Object)
166: * @see #contains(Object)
167: */
168: public boolean removeAll(Collection<?> c) {
169: boolean modified = false;
170:
171: if (size() > c.size()) {
172: for (Iterator<?> i = c.iterator(); i.hasNext();)
173: modified |= remove(i.next());
174: } else {
175: for (Iterator<?> i = iterator(); i.hasNext();) {
176: if (c.contains(i.next())) {
177: i.remove();
178: modified = true;
179: }
180: }
181: }
182: return modified;
183: }
184:
185: }
|