Background:
Ever since I found out you can Use Custom Types in Map Keys and Sets, I wondered if you can map data by the hashCode
value. I suspect it's a bad idea.
I understand the basics of how hash tables work, and I know collision is possible, but I am not sure how to measure the probability. I found this article which has a bunch of useful information and seems to confirm my hunch.
- Does
Apex
also have 232 possible values?- (looks to me like the same max int)
- Can the
hashCode
values for the same object really change? - Would the proposed
sha1
alternative be computationally expensive inApex
?
Scenario:
I have a Location
object (~2400 records) which I want to sync from an address field. Since this functionality involves creating child records, I want a way to quickly check if an address is already in the system. If it already exists, simply don't create the record. If they added a rule to duplicate management where you just drop records that already exist, I could just use that. So how viable is it to use hashCode
for de-duplication purposes?
public class CompositeAddress
{
final Id accountId;
final String street, city, state, postal;
public CompositeAddress
(Id accountId, String street, String city, String state, String postal)
{
this.accountId = accountId;
this.street = street;
this.city = city;
this.state = state;
this.postal = postal;
}
public Integer hashCode()
{
return xor(street.hashCode(), xor(city.hashCode(),
xor(state.hashCode(), postal.hashCode())
));
}
Integer xor(Integer a, Integer b) { return a ^ b; }
}
Alternatives:
- Just query all siblings and use
CompositeAddress
as a map key. - Construct a hash using the
sha1
algorithm. - Concatenate values into a text key.
I think a collision probability of < 0.5% is tolerable, but I'm not sure if my data set fits within that bound. My bigger concern is, if the algorithm can actually hash the same object in different ways, I might create duplicate records by trusting the result.