Here's the situation: I want to test 2 objects for uniqueness based on 2 different ID's. Example:
// Note I'm using JSON notation to keep things simple; the actual code
// is with Java Objects
// OBJECT A
{
main_id: 0,
id_a: 123,
id_b: 456
}
// OBJECT B
{
main_id: 1,
id_a: 123,
id_b: 456
}
// OBJECT C
{
main_id: 2,
id_a: 123,
id_b: 789
}
In the Example, Objects A and B are the same because id_a
and id_b
are the same, and Object C is different.
To determine this in the code, I'm planning on converting both ID's to a string and concatenating them together with a separator char in the middle (e.g., "{id_a},{id_b}"
), then adding them to a Set<String>
to test for uniqueness.
My question is, is there a better way? (By better, I mean more efficient and/or less kludgy)
If you want to use HashSet
, you can override hashCode
and equals
to exclusively look at those two members.
Hash code: (31
is just a prime popularly used for hashing in Java)
return 31*id_a + id_b;
Equals: (to which you'll obviously need to add instanceof
checks and type conversion)
return id_a == other.id_a && id_b == other.id_b;
If you don't want to bind these functions to the class because it's used differently elsewhere, but you still want to use HashSet
, you could consider:
Creating an intermediate class to be stored in the set, which will contain your class as a member and implement the above methods appropriately.
Use your string approach
Use HashSet<Point>
- Point
is not ideal for non-coordinate purposes as the members are simply named x
and y
, but I do find it useful to have such a class available, at least for non-production code.
Alternatively, if you want to use TreeSet
, you could have your class implement Comparable
(overriding compareTo
) or provide a Comparator
for the TreeSet
, both of which would compare primarily on the one id, and secondarily on the other.
The basic idea would look something like this:
if (objectA.id_a != objectB.id_a)
return Integer.compare(objectA.id_a, objectB.id_a);
return Integer.compare(objectA.id_b, objectB.id_b);