@@ -67,11 +67,13 @@ public boolean add(T element) {
67
67
resize (capacity () * 2 ); // Resize to double the capacity.
68
68
}
69
69
70
+ // Number of collisions encountered when attempting to insert the element into its rightful bucket
70
71
int collisions = 0 ;
71
72
while (collisions < capacity ()) {
72
73
int bucketIndex = hashFunction (element , collisions );
73
74
74
- // Insert into empty bucket.
75
+ // Insert into empty bucket. An empty bucket is defined as one that contains either a
76
+ // Tombstone, or null.
75
77
if (isEmptyBucket (bucketIndex )) {
76
78
buckets [bucketIndex ] = element ;
77
79
this .size ++;
@@ -82,6 +84,10 @@ public boolean add(T element) {
82
84
collisions ++;
83
85
}
84
86
87
+ // This line will only be reached if the number of empty buckets is zero.
88
+ // With the resizing mechanism, the HashSet/buckets will expand to a larger capacity when a
89
+ // certain threshold is reached. This means that there will always be empty buckets for adding of elements.
90
+ assert false : "should never reach this line under normal circumstances, due to resizing mechanism" ;
85
91
return false ;
86
92
}
87
93
@@ -112,6 +118,8 @@ public boolean remove(T element) {
112
118
int bucketIndex = hashFunction (element , collisions );
113
119
114
120
// Element is not removed, because it is not in the Set.
121
+ // Unlike HashSet::add, HashSet::remove ignores buckets containing Tombstones.
122
+ // Refer to README for a more detailed explanation.
115
123
if (isNullBucket (bucketIndex )) {
116
124
return false ;
117
125
}
@@ -146,13 +154,18 @@ public boolean contains(T element) {
146
154
// added to bucket 3 instead of bucket 1, or bucket 2.
147
155
// Similarly, to maintain that invariant, delete will not replace the element with null, but with a
148
156
// marker (Tombstone).
157
+ // If a bucket contains null in the probe sequence, we can be sure that the Set does not
158
+ // contain the element, and return false immediately.
159
+ // Unlike HashSet::add, HashSet::contains ignores buckets containing Tombstones.
160
+ // Refer to README for a more detailed explanation.
149
161
if (isNullBucket (bucketIndex )) {
150
162
return false ;
151
163
}
152
164
153
165
if (buckets [bucketIndex ].equals (element )) {
154
166
return true ;
155
167
}
168
+
156
169
// Skips Tombstones/Deleted elements.
157
170
collisions ++;
158
171
}
0 commit comments