Based on the accepted answer in this question: How does Set ensure equatability in Swift?
The hashValue
is used for the first test for uniqueness. If the hashValue
matches another element's hashValue
, then ==
is used as the backup testing.
But still, behind the scene Set has to store a unique identifier for each element. Consider this example:
struct Country {
let name: String
let capital: String
}
extension Country: Hashable {
static func == (lhs: Country, rhs: Country) -> Bool {
return lhs.name == rhs.name && lhs.capital == rhs.capital
}
var hashValue: Int {
return name.hashValue ^ capital.hashValue
}
}
let singapore = Country(name: "Singapore", capital: "Singapore")
let monaco = Country(name: "Monaco", capital: "Monaco")
singapore.hashValue // returns 0
monaco.hashValue // returns 0
var countries: Set<Country> = []
countries.insert(singapore)
countries.insert(monaco)
countries // Contains both singapore and monaco
As you can see, some countries have the same name as of their capitals. And this will generate hashValue
collision. The set will run more expensive ==
to determine its uniqueness which might be not O(1)
. But after doing this comparison, Set has to generate the unique identifier for this element to store behind the scene.
The question: How does set generate unique identifier for collided element like this?