package com.limegroup.gnutella.util; import java.util.*; /** * a HashSet which allows us to use custom hashCode and equals methods for * the objects contained inside. */ public class HasherSet extends HashSet { private static final Hasher DEFAULT = new DefaultHasher(); /** the <tt> Hasher </tt> instance this set will use for its elements */ private Hasher _hasher; /** creates a new instance with the provided Hasher */ public HasherSet(Hasher h){ _hasher =h; } /** creates a new instance with the default hasher, which does nothing */ public HasherSet() { _hasher=DEFAULT; } public HasherSet(Hasher h, Collection c) { _hasher = h; addAll(c); } public HasherSet(Collection c) { this(DEFAULT,c); } //TODO: override the other constructors - with size, existing collection, etc. /* (non-Javadoc) * @see java.util.Collection#add(java.lang.Object) */ public boolean add(Object arg0) { return super.add(wrap(arg0)); } /* (non-Javadoc) * @see java.util.Collection#addAll(java.util.Collection) */ public boolean addAll(Collection arg0) { return super.addAll(wrap(arg0)); } /* (non-Javadoc) * @see java.util.Collection#contains(java.lang.Object) */ public boolean contains(Object o) { return super.contains(wrap(o)); } /* (non-Javadoc) * @see java.util.Collection#containsAll(java.util.Collection) */ public boolean containsAll(Collection arg0) { return super.containsAll(wrap(arg0)); } /* (non-Javadoc) * @see java.lang.Iterable#iterator() */ public Iterator iterator() { return new UnwrapIterator(); } /* (non-Javadoc) * @see java.util.Collection#remove(java.lang.Object) */ public boolean remove(Object o) { return super.remove(wrap(o)); } /* (non-Javadoc) * @see java.util.Collection#retainAll(java.util.Collection) */ public boolean retainAll(Collection arg0) { return super.retainAll(wrap(arg0)); } /** * @param c a collection that will interact with this * @return a collection of Wrapper objects, wrapping each element in the * original collection */ private Collection wrap(Collection c) { if (c instanceof HasherSet) return c; HashSet tmp = new HashSet(); for (Iterator i = c.iterator();i.hasNext();){ Object next = i.next(); tmp.add(wrap(next)); } return tmp; } private Wrapper wrap(Object o) { if (o instanceof Wrapper) return ((Wrapper)o); else return new Wrapper(o); } private final class Wrapper { private final Object _obj; public Wrapper(Object o) { _obj = o; } public int hashCode() { return _hasher.hash(_obj); } public boolean equals(Object other) { if (other instanceof Wrapper) return _hasher.areEqual(_obj,((Wrapper)other).getObj()); return false; } public Object getObj() { return _obj; } } private final class UnwrapIterator implements Iterator { private final Iterator _iter; public UnwrapIterator() { _iter = HasherSet.super.iterator(); } public boolean hasNext() { return _iter.hasNext(); } public Object next() { Wrapper wr = (Wrapper)_iter.next(); return wr.getObj(); } public void remove() { _iter.remove(); } } /** * a default hasher which delegates to the object's methods. */ private static final class DefaultHasher implements Hasher { public int hash(Object o) { return o.hashCode(); } public boolean areEqual(Object a, Object b) { return a.equals(b); } } }