1. /*
  2. * @(#)AbstractSet.java 1.26 04/02/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util;
  8. /**
  9. * This class provides a skeletal implementation of the <tt>Set</tt>
  10. * interface to minimize the effort required to implement this
  11. * interface. <p>
  12. *
  13. * The process of implementing a set by extending this class is identical
  14. * to that of implementing a Collection by extending AbstractCollection,
  15. * except that all of the methods and constructors in subclasses of this
  16. * class must obey the additional constraints imposed by the <tt>Set</tt>
  17. * interface (for instance, the add method must not permit addition of
  18. * multiple instances of an object to a set).<p>
  19. *
  20. * Note that this class does not override any of the implementations from
  21. * the <tt>AbstractCollection</tt> class. It merely adds implementations
  22. * for <tt>equals</tt> and <tt>hashCode</tt>.<p>
  23. *
  24. * This class is a member of the
  25. * <a href="{@docRoot}/../guide/collections/index.html">
  26. * Java Collections Framework</a>.
  27. *
  28. * @author Josh Bloch
  29. * @author Neal Gafter
  30. * @version 1.26, 02/19/04
  31. * @see Collection
  32. * @see AbstractCollection
  33. * @see Set
  34. * @since 1.2
  35. */
  36. public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {
  37. /**
  38. * Sole constructor. (For invocation by subclass constructors, typically
  39. * implicit.)
  40. */
  41. protected AbstractSet() {
  42. }
  43. // Comparison and hashing
  44. /**
  45. * Compares the specified object with this set for equality. Returns
  46. * <tt>true</tt> if the given object is also a set, the two sets have
  47. * the same size, and every member of the given set is contained in
  48. * this set. This ensures that the <tt>equals</tt> method works
  49. * properly across different implementations of the <tt>Set</tt>
  50. * interface.<p>
  51. *
  52. * This implementation first checks if the specified object is this
  53. * set; if so it returns <tt>true</tt>. Then, it checks if the
  54. * specified object is a set whose size is identical to the size of
  55. * this set; if not, it returns false. If so, it returns
  56. * <tt>containsAll((Collection) o)</tt>.
  57. *
  58. * @param o Object to be compared for equality with this set.
  59. * @return <tt>true</tt> if the specified object is equal to this set.
  60. */
  61. public boolean equals(Object o) {
  62. if (o == this)
  63. return true;
  64. if (!(o instanceof Set))
  65. return false;
  66. Collection c = (Collection) o;
  67. if (c.size() != size())
  68. return false;
  69. try {
  70. return containsAll(c);
  71. } catch(ClassCastException unused) {
  72. return false;
  73. } catch(NullPointerException unused) {
  74. return false;
  75. }
  76. }
  77. /**
  78. * Returns the hash code value for this set. The hash code of a set is
  79. * defined to be the sum of the hash codes of the elements in the set.
  80. * This ensures that <tt>s1.equals(s2)</tt> implies that
  81. * <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt>
  82. * and <tt>s2</tt>, as required by the general contract of
  83. * Object.hashCode.<p>
  84. *
  85. * This implementation enumerates over the set, calling the
  86. * <tt>hashCode</tt> method on each element in the collection, and
  87. * adding up the results.
  88. *
  89. * @return the hash code value for this set.
  90. */
  91. public int hashCode() {
  92. int h = 0;
  93. Iterator<E> i = iterator();
  94. while (i.hasNext()) {
  95. E obj = i.next();
  96. if (obj != null)
  97. h += obj.hashCode();
  98. }
  99. return h;
  100. }
  101. /**
  102. * Removes from this set all of its elements that are contained in
  103. * the specified collection (optional operation).<p>
  104. *
  105. * This implementation determines which is the smaller of this set
  106. * and the specified collection, by invoking the <tt>size</tt>
  107. * method on each. If this set has fewer elements, then the
  108. * implementation iterates over this set, checking each element
  109. * returned by the iterator in turn to see if it is contained in
  110. * the specified collection. If it is so contained, it is removed
  111. * from this set with the iterator's <tt>remove</tt> method. If
  112. * the specified collection has fewer elements, then the
  113. * implementation iterates over the specified collection, removing
  114. * from this set each element returned by the iterator, using this
  115. * set's <tt>remove</tt> method.<p>
  116. *
  117. * Note that this implementation will throw an
  118. * <tt>UnsupportedOperationException</tt> if the iterator returned by the
  119. * <tt>iterator</tt> method does not implement the <tt>remove</tt> method.
  120. *
  121. * @param c elements to be removed from this set.
  122. * @return <tt>true</tt> if this set changed as a result of the call.
  123. *
  124. * @throws UnsupportedOperationException removeAll is not supported
  125. * by this set.
  126. * @throws NullPointerException if the specified collection is null.
  127. * @see #remove(Object)
  128. * @see #contains(Object)
  129. */
  130. public boolean removeAll(Collection<?> c) {
  131. boolean modified = false;
  132. if (size() > c.size()) {
  133. for (Iterator<?> i = c.iterator(); i.hasNext(); )
  134. modified |= remove(i.next());
  135. } else {
  136. for (Iterator<?> i = iterator(); i.hasNext(); ) {
  137. if (c.contains(i.next())) {
  138. i.remove();
  139. modified = true;
  140. }
  141. }
  142. }
  143. return modified;
  144. }
  145. }