Set如何解决哈希冲突?

时间:2017-08-11 07:59:42

标签: swift

根据此问题中接受的答案:How does Set ensure equatability in Swift?
hashValue用于第一次测试唯一性。如果hashValue与其他元素的hashValue匹配,则==将用作备份测试。

但是,在场景后面Set必须为每个元素存储一个唯一的标识符。考虑这个例子:

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

如您所见,有些国家/地区与其首都的名称相同。这将产生hashValue碰撞。该集将运行更昂贵的==以确定其唯一性,可能不是O(1)。但在进行此比较后,Set必须生成此元素的唯一标识符以存储在场景后面。

问题:如何为这样的碰撞元素生成唯一标识符?

1 个答案:

答案 0 :(得分:1)

似乎哈希值仅用于标识用于在内部插入元素的存储桶(不存储哈希值),但使用==来比较是否使用了该元素。如果集合存储增长,还需要重新整理所有元素。

您可以在讨论中here获取更多信息。