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 * @deprecated */ public class EquivalentHashSet<E> extends AbstractSet<E> { /** * 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<E, Boolean> 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<E, Boolean>(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<E, Boolean>( 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<E> 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 <tt>null</tt> 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 <tt>s1</tt> and <tt>s2</tt>, as required by the general * contract of {@link Object#hashCode}. * * <p>This implementation iterates over the set, calling the * <tt>hashCode</tt> 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<E> i = iterator(); while (i.hasNext()) { E obj = i.next(); if (obj != null) h += entryEq.hashCode(obj); } return h; } }