org.infinispan.commons.equivalence.EquivalentHashSet Maven / Gradle / Ivy
package org.infinispan.commons.equivalence;
import java.util.AbstractSet;
import java.util.Iterator;
/**
* Custom hash-based set which accepts no null values, where
* equality and hash code calculations are done based on passed
* {@link org.infinispan.commons.equivalence.Equivalence} function implementations for values,
* as opposed to relying on their own equals/hashCode/toString implementations.
* This is handy when using key/values whose mentioned methods cannot be
* overriden, i.e. arrays, and in situations where users want to avoid using
* wrapper objects.
*
* @author Galder Zamarreño
* @since 5.3
*/
public class EquivalentHashSet extends AbstractSet {
/**
* Equivalence function for the entries of this hash set, providing
* functionality to check equality, calculate hash codes...etc of the
* stored entries.
*/
private final Equivalence super E> entryEq;
/**
* The underlying map. Uses Boolean.TRUE as value for each element.
*/
private final EquivalentHashMap m;
/**
* Constructs a new, empty set, with a given equivalence function
*
* @param entryEq the Equivalence function to be used to compare entries
* in this set.
*/
public EquivalentHashSet(Equivalence super E> entryEq) {
this.entryEq = entryEq;
m = new EquivalentHashMap(entryEq, AnyEquivalence.BOOLEAN);
}
/**
* Constructs a new, empty set, with a given initial capacity and a
* particular equivalence function to compare entries.
*
* @param initialCapacity this set's initial capacity
* @param entryEq the Equivalence function to be used to compare entries
* in this set.
*/
public EquivalentHashSet(int initialCapacity, Equivalence super E> entryEq) {
this.entryEq = entryEq;
m = new EquivalentHashMap(
initialCapacity, entryEq, AnyEquivalence.BOOLEAN);
}
/**
* Returns an iterator over the elements in this set.
*
* @return an iterator over the elements in this set
*/
@Override
public Iterator iterator() {
return m.keySet().iterator();
}
/**
* Returns the number of elements in this set. If this set
* contains more than {@code Integer.MAX_VALUE} elements, it
* returns {@code Integer.MAX_VALUE}.
*
* @return the number of elements in this set
*/
@Override
public int size() {
return m.size();
}
/**
* Returns {@code true} if this set contains no elements.
*
* @return {@code true} if this set contains no elements
*/
@Override
public boolean isEmpty() {
return m.isEmpty();
}
/**
* Returns {@code true} if this set contains the specified element.
*
* @param o the object to be checked for containment in this set
* @return {@code true} if this set contains the specified element
*/
@Override
public boolean contains(Object o) {
return m.containsKey(o);
}
/**
* Adds the specified element to this set if it is not already present.
*
* @param o element to be added to this set
* @return {@code true} if the set did not already contain the specified
* element
*/
@Override
public boolean add(E o) {
return m.put(o, Boolean.TRUE) == null;
}
/**
* Removes the specified element from this set if it is present.
*
* @param o object to be removed from this set, if present
* @return {@code true} if the set contained the specified element
*/
@Override
public boolean remove(Object o) {
return m.remove(o) != null;
}
/**
* Removes all of the elements from this set.
*/
@Override
public void clear() {
m.clear();
}
/**
* Returns the hash code value for this set using the {@link Equivalence}
* function associated with it. The hash code of a set is defined to be
* the sum of the hash codes of the elements in the set, where the hash
* code of a null element is defined to be zero. This ensures that
* {@link Equivalence#equals(Object s1, Object s2)} implies that
* {@link Equivalence#hashCode(Object s1)}=={@link Equivalence#hashCode(Object s2)}
* for any two sets s1 and s2, as required by the general
* contract of {@link Object#hashCode}.
*
* This implementation iterates over the set, calling the
* hashCode method on each element in the set, and adding up
* the results.
*
* @return the hash code value for this set
*/
@Override
public int hashCode() {
int h = 0;
Iterator i = iterator();
while (i.hasNext()) {
E obj = i.next();
if (obj != null)
h += entryEq.hashCode(obj);
}
return h;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy