Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IEqualityComparer interface in Java

More specifically I want an interface to compare objects which can be only compared for equality [e.g. complex numbers] but don't have total order on them. It should have [Note that it only returns a boolean yes/no]

boolean Equals(T object1, T object2);

and a hashcode function. So that when I distribute them into buckets using objects say to collect "equal" objects, 2 "equal" objects don't end up in two different buckets.

int getHashCode(T object);

Does Java have one? I searched and couldn't find it.

I am trying to use this in Hadoop Map Reduce to distribute "equal" objects to same reduce job so that I can operate on all "equal" objects. I only care about whether objects are equal or not and don't need total order. But if two objects are equal they should have same hash code. Otherwise they will end up in two different reduce jobs.

Please note that I know about equals and hashcode of object. But I want an external comparator which say depends on only part of an object. So object's notion of equality differs from mine.

like image 853
Fakrudeen Avatar asked Jan 29 '11 15:01

Fakrudeen


3 Answers

There's no built-in type that is used for this in Java. It's a "hole" in the collections design, IMO. There's the string-specific Collator class which is about as close as it gets, I'm afraid.

There's no way of customizing the built-in maps to use a specific kind of equality comparison, worse luck. It's entirely reasonable to want this functionality, and a real pain that it's not already present.

You could create your own such interface of course, and write your own map variants which use it... but having to do so sucks :(

like image 98
Jon Skeet Avatar answered Nov 11 '22 10:11

Jon Skeet


The type you want is Guava's Equivalence. However, you may be disappointed, as in Java Collection and Map are fairly rigidly specified in terms of Object.equals, and you will not find implementations of those in Guava that use an alternate equivalence. You can, however, simulate that behavior a bit using myEquivalence.wrap(myObject).

like image 20
Kevin Bourrillion Avatar answered Nov 11 '22 11:11

Kevin Bourrillion


I would suggest using a function based approach to generate the buckets like the MultiMaps.index() method in Google collections (now Guava) does. They use a Function<V,K> which maps objects of type V to keys of type K (in your case the buckets).

like image 2
Florian Avatar answered Nov 11 '22 09:11

Florian