This hash set allows arbitrary capacities sized hash sets to be created, * including hash sets of size 0. When resizing is necessary due to * objects being added, it resizes to the next largest capacity that is * at least 1.5 times *
HashSet
?Java's hash set implementation requires hash tables with * capacities that are even powers of 2. This allows a very quick * modulus operation on hash codes by using a mask, but restricts * the size of hash sets to be powers of 2. * *
The current implementation uses linear probing with a step size * of 1 for the case of hash code collisions. This means that if the * position for an entry is full, the next position is considered * (wrapping to the beginning at the end of the array). * *
We borrowed the supplemental hashing function from
* {@link java.util.HashMap} (version ID 1.73). If the
* initial hashFunction is h
the supplemental
* hash function is computed by:
*
*
* * This is required to scramble the hash code of strings * that share the same prefix with a different final character from * being adjacent. Recall that the hash code for strings* static int supplementalHash(int n) { * int n2 = n ^ (n >>> 20) ^ (n >>> 12); * return n2 ^ (n2 >>> 7) ^ (n2 >>> 4); * }
s
* consisting of characters s[0], ..., s[n-1]
is
* defined in {@link String#hashCode()} to be:
*
* * ** s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
As of this release, sets will never be resized downward. * *
Equality and Hash Codes
* * Compact hash sets satisfy the specification of the * the equality metho, {@link #equals(Object)}, and hash code * method {@link #hashCode()} specified by the {@link java.util.Set} interface. * *The implementations are inherited from the superclass * {@link AbstractSet}, which uses the underlying iterators. * *
Note that this operation does not affect the * underlying capacity of the set itself. */ @Override public void clear() { alloc(1); } /** * Returns {@code true} if this set contains the specified object. * * @param o Object to test. * @return {@code true} if this set contains the specified object. * @throws NullPointerException If the specified object is null. * @throws ClassCastException If the type of this object is incompatible * with this set. */ @Override public boolean contains(Object o) { if (o == null) { String msg = "Compact hash sets do not support null objects."; throw new NullPointerException(msg); } Object o2 = mBuckets[findSlot(o)]; return o2 != null && o.equals(o2); } /** * Returns an iterator over the elements in this set. The * iterator supports the {@link Iterator#remove()} operation, * which is not considered a concurrent modification. * *
Iteration order for sets is not guaranteed to be * stable under adds or deletes, or for sets of different * capacities containing the same elements. * *
The set must not be modified by other operations
* while an iteration is in process. Doing so may cause
* an illegal state and unpredictable behavior such as
* null pointer or array index exceptions.
*
* @return Iterator over the set elements.
*/
@Override
public Iterator Implementation Note: Unlike the implementation the
* parent class {@link AbstractSet} inherits from its
* parent class {@link java.util.AbstractCollection}, this implementation
* iterates over the argument collection, removing each of its
* elements.
*
* @param collection Collection of objects to remove.
* @return {@code true} if the set was modified as a result.
* @throws NullPointerException If any of the collection members is null, or
* if the specified collection is itself null.
* @throws ClassCastException If attempting to remove a member of the
* collection results in a cast exception.
*/
@Override
public boolean removeAll(Collection> collection) {
boolean modified = false;
for (Object o : collection)
if (remove(o))
modified = true;
return modified;
}
/**
* Remove all elements from this set that are not members of the
* specified collection, returning {@code true} if this set was
* modified as a result of the operation.
*
* Implementation Note: Unlike the implementation that
* the parent class {@link AbstractSet} inherits from {@link
* java.util.AbstractCollection}, this implementation directly
* visits the underlying hash entries rather than invoking the
* overhead of an iterator.
*
* @param collection Collection of objects to retain.
* @return {@code true} if this set was modified as a result of
* the operation.
* @throws ClassCastException If comparing elements of the
* specified collection to elements of this set throws a class
* cast exception.
* @throws NullPointerException If the specified collection is
* {@code null}.
*
*/
@Override
public boolean retainAll(Collection> collection) {
boolean modified = false;
for (int i = 0; i < mBuckets.length; ++i) {
if (mBuckets[i] != null && collection.contains(mBuckets[i])) {
modified = true;
mBuckets[i] = null;
tampCollisions(i);
--mSize;
}
}
return modified;
}
/**
* Returns the number of objects in this set.
*
* @return The number of objects in this set.
*/
@Override
public int size() {
return mSize;
}
/**
* Returns an object array containing all of the members of this
* set. The order of elements in the array is the iteration
* order, but this is not guaranteed to be stable under
* modifications or changes in capacity.
*
* The returned array is fresh and may be modified without
* affect this set.
*
* @return Array of objects in this set.
*/
@Override
public Object[] toArray() {
Object[] result = new Object[mSize];
int nextIndex = 0;
for (int i = 0; i < mBuckets.length; ++i)
if (mBuckets[i] != null)
result[nextIndex++] = mBuckets[i];
return result;
}
/**
* Returns an array of elements contained in this set, the runtime type
* of which is that of the specified array argument.
*
* If the specified array argument is long enough to hold all
* of the elements in this set, it will be filled starting from
* index 0. If the specified array is longer than the size of the
* set, the array entry following the last entry filled by this
* set will be set to {@code null}.
*
* If the specified array is not long enough to hold all of
* the elements, a new array will be created of the appropriate
* type through reflection.
*
* @param array Array of values determining type of output and containing
* output elements if long enough.
* @param