1. /*
  2. * @(#)AbstractSet.java 1.19 03/01/23
  3. *
  4. * Copyright 2003 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 intances 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. * @version 1.19, 01/23/03
  30. * @see Collection
  31. * @see AbstractCollection
  32. * @see Set
  33. * @since 1.2
  34. */
  35. public abstract class AbstractSet extends AbstractCollection implements Set {
  36. /**
  37. * Sole constructor. (For invocation by subclass constructors, typically
  38. * implicit.)
  39. */
  40. protected AbstractSet() {
  41. }
  42. // Comparison and hashing
  43. /**
  44. * Compares the specified object with this set for equality. Returns
  45. * <tt>true</tt> if the given object is also a set, the two sets have
  46. * the same size, and every member of the given set is contained in
  47. * this set. This ensures that the <tt>equals</tt> method works
  48. * properly across different implementations of the <tt>Set</tt>
  49. * interface.<p>
  50. *
  51. * This implementation first checks if the specified object is this
  52. * set; if so it returns <tt>true</tt>. Then, it checks if the
  53. * specified object is a set whose size is identical to the size of
  54. * this set; if not, it it returns false. If so, it returns
  55. * <tt>containsAll((Collection) o)</tt>.
  56. *
  57. * @param o Object to be compared for equality with this set.
  58. * @return <tt>true</tt> if the specified object is equal to this set.
  59. */
  60. public boolean equals(Object o) {
  61. if (o == this)
  62. return true;
  63. if (!(o instanceof Set))
  64. return false;
  65. Collection c = (Collection) o;
  66. if (c.size() != size())
  67. return false;
  68. try {
  69. return containsAll(c);
  70. } catch(ClassCastException unused) {
  71. return false;
  72. } catch(NullPointerException unused) {
  73. return false;
  74. }
  75. }
  76. /**
  77. * Returns the hash code value for this set. The hash code of a set is
  78. * defined to be the sum of the hash codes of the elements in the set.
  79. * This ensures that <tt>s1.equals(s2)</tt> implies that
  80. * <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt>
  81. * and <tt>s2</tt>, as required by the general contract of
  82. * Object.hashCode.<p>
  83. *
  84. * This implementation enumerates over the set, calling the
  85. * <tt>hashCode</tt> method on each element in the collection, and
  86. * adding up the results.
  87. *
  88. * @return the hash code value for this set.
  89. */
  90. public int hashCode() {
  91. int h = 0;
  92. Iterator i = iterator();
  93. while (i.hasNext()) {
  94. Object obj = i.next();
  95. if (obj != null)
  96. h += obj.hashCode();
  97. }
  98. return h;
  99. }
  100. /**
  101. * Removes from this set all of its elements that are contained in
  102. * the specified collection (optional operation).<p>
  103. *
  104. * This implementation determines which is the smaller of this set
  105. * and the specified collection, by invoking the <tt>size</tt>
  106. * method on each. If this set has fewer elements, then the
  107. * implementation iterates over this set, checking each element
  108. * returned by the iterator in turn to see if it is contained in
  109. * the specified collection. If it is so contained, it is removed
  110. * from this set with the iterator's <tt>remove</tt> method. If
  111. * the specified collection has fewer elements, then the
  112. * implementation iterates over the specified collection, removing
  113. * from this set each element returned by the iterator, using this
  114. * set's <tt>remove</tt> method.<p>
  115. *
  116. * Note that this implementation will throw an
  117. * <tt>UnsupportedOperationException</tt> if the iterator returned by the
  118. * <tt>iterator</tt> method does not implement the <tt>remove</tt> method.
  119. *
  120. * @param c elements to be removed from this set.
  121. * @return <tt>true</tt> if this set changed as a result of the call.
  122. *
  123. * @throws UnsupportedOperationException removeAll is not supported
  124. * by this set.
  125. * @throws NullPointerException if the specified collection is null.
  126. * @see #remove(Object)
  127. * @see #contains(Object)
  128. */
  129. public boolean removeAll(Collection c) {
  130. boolean modified = false;
  131. if (size() > c.size()) {
  132. for (Iterator i = c.iterator(); i.hasNext(); )
  133. modified |= remove(i.next());
  134. } else {
  135. for (Iterator i = iterator(); i.hasNext(); ) {
  136. if(c.contains(i.next())) {
  137. i.remove();
  138. modified = true;
  139. }
  140. }
  141. }
  142. return modified;
  143. }
  144. }