Last active
October 5, 2016 18:31
-
-
Save vkorobkov/24055fd77ce869f689112e60a6125c24 to your computer and use it in GitHub Desktop.
When you need a custom hashcode/equals in a Set
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.AbstractCollection; | |
import java.util.HashSet; | |
import java.util.Iterator; | |
import java.util.Set; | |
public class DecoratedSet<K> extends AbstractCollection<K> implements Set<K> { | |
@FunctionalInterface | |
public interface Decorator<K> { | |
Wrapped<K> wrap(K element); | |
} | |
@FunctionalInterface | |
public interface Wrapped<K> { | |
K getOriginal(); | |
} | |
private final Set set; | |
private final Decorator<K> decorator; | |
public DecoratedSet(Decorator<K> decorator) { | |
this(new HashSet(), decorator); | |
} | |
public DecoratedSet(Set set, Decorator<K> decorator) { | |
this.set = set; | |
this.decorator = decorator; | |
} | |
@Override | |
public int size() { | |
return set.size(); | |
} | |
@Override | |
public boolean contains(Object o) { | |
return set.contains(wrap(o)); | |
} | |
@Override | |
public Iterator<K> iterator() { | |
Iterator<Wrapped<K>> iterator = set.iterator(); | |
return new Iterator<K>() { | |
@Override | |
public boolean hasNext() { | |
return iterator.hasNext(); | |
} | |
@Override | |
public K next() { | |
return iterator.next().getOriginal(); | |
} | |
@Override | |
public void remove() { | |
iterator.remove(); | |
} | |
}; | |
} | |
@Override | |
public boolean add(K k) { | |
return set.add(wrap(k)); | |
} | |
@Override | |
public boolean remove(Object o) { | |
return set.remove(wrap(o)); | |
} | |
@Override | |
public void clear() { | |
set.clear(); | |
} | |
private Wrapped<K> wrap(Object k) { | |
return decorator.wrap((K)k); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sometimes you want to have a hashCode/equals which depend on an external context as an addition to internal objects state.
Here's an example of usage(unit test written in groovy+spock framework):