I think the enum approach would make sense from an object-oriented point of view, but this is dangerous. It can break the contract equals() and hashCode() (reflexivity, symmetry, and transitivity). For example, inserting an instance that uses the first equivalence strategy and an instance that uses the second equivalence strategy in the same Set can cause problems.
If you need different equivalence relationships, you should leave them outside your class. Equivalence allows you to do just that: you extract the equivalence logic (equals () / hashCode ()) by implementing equivalence and overriding the doHash() and doEquivalent() methods.
Then, when you want to use Collection based on one equivalence or another, you use Equivalence.wrap() . For example, you can emulate an IdentityHashSet by doing:
Set<Equivalence.Wrapper<String>> identityHashSet = Sets.newHashSet(); String a1 = "a"; String a2 = new String("a"); String b = "b"; identityHashSet.add(Equivalences.identity().wrap(a1)); identityHashSet.add(Equivalences.identity().wrap(a2)); identityHashSet.add(Equivalences.identity().wrap(a3));
Of course, you can use ForwardingSet to automate the wrapping / unpacking of your elements.
Guava has more information on this issue .
source share