tags:

views:

84

answers:

4

I have several Sets that store the objects of the same class, but I want to specify a different identity function for each of them (i.e. say, in one set A==B if A.x==B.x, while in another A==B if A.y==B.y).

Currently I use TreeSets with different Comparators defined for each. I am wondering how the same thing can be done if I want to switch to HashSets. Java does not allow passing a separate hash function in the same way it allows Comparators for Sorted/Tree-based Collections. The only way that I can think of doing it would involve creating a different wrapper class and implementing the hashCode() method in each for the elements of each HashSet. Is there a better way of doing this?

+7  A: 

How about creating separate subclasses for each set. The only difference for each subclass would be the overridden hash function that meets your criteria.

Poindexter
You could implement the subclasses as private inner classes and provide a factory method to obtain the equality semantics you want. This encapsulates the choice completely
Andrew
+3  A: 

I'm not aware of a better way to do it. Your proposed solution (wrapper classes with different comparison logic) sounds very reasonable.

You mentioned implementing the hashCode method - don't forget to implement equals as well.

Eli Acherkan
+2  A: 

There is another option: You can copy the source for HashMap and replace the method hash(Object key) with something else (for example, a call to a Hasher that works like the Comparator of the TreeMap).

Aaron Digulla
good. Just remember to implement the Collection interface.
Bozho
Thanks. I guess this is the best thing to do. I am accepting Peter Lawry's answer since he suggests using an off-the-shelf implementation instead of coding my own.
MAK
+2  A: 

You could try using THashSet in GNU Trove, This support multiple hashing strategies.

Peter Lawrey