Multiple equality relations?
Hi everyone,
I'm not exactly new to Java, but I have a more extensive background in C++.
My problem is I'd like to define two different equality relations on the same class.
Using comparators, I can define additional orderings between elements aside from the "natural" ordering provided by the Comparable interface. I can then pass this comparator to a TreeSet to get the appropriate ordering, which in the following example eliminates duplicates either based on the unique ID (don't allow the same object twice) or the content (don't allow the same content twice).
Code:
class A implements Comparable<A> {
final int uniqueID;
int content;
int compareTo(A other) {
return this.uniqueID - other.uniqueID;
}
public static ContentComparator implements Comparator<A> {
public int compare(A a1, A a2) {
return a1.content - a2.content;
}
}
}
TreeSet<A> noIDDuplicates = new TreeSet();
TreeSet<A> noContentDuplicates = new TreeSet(new ContentComparator());
However, I can't seem to find a way of doing the same thing using HashSets. The HashSet implementation uses the equals() and hashCode() functions to test for equality, and I haven't seen any constructors taking a custom hashCode/equality functions as parameters.
Code:
class A implements Comparable<A> {
...
boolean equals(A other) {
return this.uniqueID == other.uniqueID; // or equivalently, return this == other;
}
int hashCode() {
return this.uniqueID;
}
}
HashSet<A> noIDDuplicates = new HashSet();
HashSet<A> noContentDuplicates = ???
In C++ additional hashing/equality pairs are supported through template parameters.
So my question then: is there another type of HashSet which accepts a custom equality relation (not the "natural" one)? Or do I have to wrap my objects in another class defining the extra relation, before adding them to the HashSet?
Thanks!
Simon
Re: Multiple equality relations?
Re: Multiple equality relations?
Quote:
Originally Posted by
IvesRogne
I'm not exactly new to Java, but I have a more extensive background in C++.
That's fine, but please concentrate on problem rather than language, even if you prefer in Java.
Re: Multiple equality relations?
Quote:
However, I can't seem to find a way of doing the same thing using HashSets.
You are comparing incomparable things. A TreeSet is a Set with guaranteed ordering, a HashSet has no guarantee on ordering.
Quote:
So my question then: is there another type of HashSet which accepts a custom equality relation (not the "natural" one)?
Not that I'm aware of.
BTW It seems wrong to me that a class would have different equality relationships. If a class is designed correctly then instances of that class are either equal to each other or they are not equal to each other. It's not a case of them being equal to each other in one circumstance but not in another. If you want to change the equality relationship then you should have a different class eg use a wrapper class as you suggested.
Re: Multiple equality relations?
Quote:
You are comparing incomparable things. A TreeSet is a Set with guaranteed ordering, a HashSet has no guarantee on ordering.
Yes I know, but I'm not interested in the actual ordering, only in finding duplicates.
I just find it odd that you can have multiple orderings (that actually also define equality relations, i.e. A is equal to B iif A.compareTo(B) == 0) but a single equality relation. Makes it simpler I guess, though. Well thanks, I'll go with the wrapper!
Re: Multiple equality relations?
Quote:
I just find it odd that you can have multiple orderings (that actually also define equality relations, i.e. A is equal to B iif A.compareTo(B) == 0)
When you are comparing two objects they can be in one of three states ie greater than, equal to or less than and I'll think you'll find most classes that accept a Comparator warn against having a comparator that returns 0 when the object equals() method does not return true.