java.util.AbstractSet抽象类继承自 AbstractCollection 抽象类,所有Set的实现类都直接或者间接继承AbstractSet父类。
AbstractSet类包括equals(),hashCode(),removeAll(c)方法,这些方法都被实现了,子类无需再重写。
AbstractSet类提供了实现Set集合的基本框架,方便HashSet、TreeSet这些子类的实现。
1 package java.util;
2
3 public abstract class AbstractSet<E> extends AbstractCollection<E> implements
4 Set<E> {
5 /**
6 * Sole constructor. (For invocation by subclass constructors, typically
7 * implicit.)
8 */
9 protected AbstractSet() {
10 }
11
12 // Comparison and hashing
13
14 /**
15 * Compares the specified object with this set for equality. Returns
16 * <tt>true</tt> if the given object is also a set, the two sets have the
17 * same size, and every member of the given set is contained in this set.
18 * This ensures that the <tt>equals</tt> method works properly across
19 * different implementations of the <tt>Set</tt> interface.
20 * <p>
21 *
22 * This implementation first checks if the specified object is this set; if
23 * so it returns <tt>true</tt>. Then, it checks if the specified object is a
24 * set whose size is identical to the size of this set; if not, it returns
25 * false. If so, it returns <tt>containsAll((Collection) o)</tt>.
26 *
27 * @param o
28 * object to be compared for equality with this set
29 * @return <tt>true</tt> if the specified object is equal to this set
30 */
31 public boolean equals(Object o) {
32 // 是否指向同一个对象?
33 if (o == this)
34 return true;
35
36 // 是否都是Set类?
37 if (!(o instanceof Set))
38 return false;
39
40 Collection c = (Collection) o;
41 // 先比较大小
42 if (c.size() != size())
43 return false;
44 try {
45 // 再比较所有的元素
46 return containsAll(c);
47 // 处理containsAll(c)抛出的异常
48 } catch (ClassCastException unused) {
49 return false;
50 } catch (NullPointerException unused) {
51 return false;
52 }
53 }
54
55 /**
56 * Returns the hash code value for this set. The hash code of a set is
57 * defined to be the sum of the hash codes of the elements in the set, where
58 * the hash code of a <tt>null</tt> element is defined to be zero. This
59 * ensures that <tt>s1.equals(s2)</tt> implies that
60 * <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt> and
61 * <tt>s2</tt>, as required by the general contract of
62 * {@link Object#hashCode}.
63 *
64 * <p>
65 * This implementation iterates over the set, calling the <tt>hashCode</tt>
66 * method on each element in the set, and adding up the results.
67 *
68 * @return the hash code value for this set
69 * @see Object#equals(Object)
70 * @see Set#equals(Object)
71 */
72 public int hashCode() {
73 int h = 0;
74 // 使用迭代器遍历所有的元素
75 Iterator<E> i = iterator();
76 while (i.hasNext()) {
77 E obj = i.next();
78 if (obj != null)
79 // 加上每个元素的hashCode
80 h += obj.hashCode();
81 }
82 return h;
83 }
84
85 /**
86 * Removes from this set all of its elements that are contained in the
87 * specified collection (optional operation). If the specified collection is
88 * also a set, this operation effectively modifies this set so that its
89 * value is the <i>asymmetric set difference</i> of the two sets.
90 *
91 * <p>
92 * This implementation determines which is the smaller of this set and the
93 * specified collection, by invoking the <tt>size</tt> method on each. If
94 * this set has fewer elements, then the implementation iterates over this
95 * set, checking each element returned by the iterator in turn to see if it
96 * is contained in the specified collection. If it is so contained, it is
97 * removed from this set with the iterator's <tt>remove</tt> method. If the
98 * specified collection has fewer elements, then the implementation iterates
99 * over the specified collection, removing from this set each element
100 * returned by the iterator, using this set's <tt>remove</tt> method.
101 *
102 * <p>
103 * Note that this implementation will throw an
104 * <tt>UnsupportedOperationException</tt> if the iterator returned by the
105 * <tt>iterator</tt> method does not implement the <tt>remove</tt> method.
106 *
107 * @param c
108 * collection containing elements to be removed from this set
109 * @return <tt>true</tt> if this set changed as a result of the call
110 * @throws UnsupportedOperationException
111 * if the <tt>removeAll</tt> operation is not supported by this
112 * set
113 * @throws ClassCastException
114 * if the class of an element of this set is incompatible with
115 * the specified collection (optional)
116 * @throws NullPointerException
117 * if this set contains a null element and the specified
118 * collection does not permit null elements (optional), or if
119 * the specified collection is null
120 * @see #remove(Object)
121 * @see #contains(Object)
122 */
123 public boolean removeAll(Collection<?> c) {
124 boolean modified = false;
125
126 // 对元素少的集合使用迭代器
127 if (size() > c.size()) {
128 for (Iterator<?> i = c.iterator(); i.hasNext();)
129 // Set集合删除元素,记录操作是否成功
130 modified |= remove(i.next());
131 } else {
132 for (Iterator<?> i = iterator(); i.hasNext();) {
133 if (c.contains(i.next())) {
134 // 迭代器删除元素,记录成功
135 i.remove();
136 modified = true;
137 }
138 }
139 }
140 return modified;
141 }
142
143 }
144