快速设置类型的哈希值是什么?

时间:2019-07-29 08:02:16

标签: swift hash set

当我阅读快速文档时,我不明白那是什么意思吗?。 类型必须是可哈希的才能存储在集合中,也就是说,该类型必须提供一种为其自身计算哈希值的方法。哈希值是一个Int值,对于所有相等比较的对象都是相同的,因此,如果a == b,则它遵循a.hashValue == b.hashValue。

1 个答案:

答案 0 :(得分:0)

Set是为提高性能而设计的。 contains(_:)上的Set方法的复杂度为O(1),这意味着无论集合的大小如何,它都需要花费恒定的时间来执行。 contains(_:)上的Array为O(n),这意味着确定数组是否包含元素的时间会随着数组大小的增加而增加。

Set如何做到这一点?它对hashValue的项目使用Set,并包含一个内部字典式结构,该结构将hashValue映射到具有hashValue的项目列表。这使得测试复杂结构(例如String)的相等性非常快,因为Set首先测试两个值是否具有相同的hashValue。如果hashValue不同,则无需检查struct本身的内容。

要测试Set contains是否为值,只需要在字典中查找hashValue,然后将该项与匹配的值进行比较即可。

因此,对于要包含在Set中的项目,提供以下功能的哈希函数很重要:

  1. 如果两个结构/对象相等,则相同。 (绝对要求
  2. 计算范围广泛的hashValues,因此项目分布广泛,不需要回落到较慢的相等检查中。 (为了获得良好的性能

以下是Hashable struct的一个示例,适用于存储在Set中:

struct Option: Hashable, CustomStringConvertible {
    var title: String
    var key: String
    var value: Int
    var description: String { return "{title: \"\(title)\", key: \"\(key)\", value: \(value)}" }

    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
        hasher.combine(key)
    }

    static func ==(lhs: Option, rhs: Option) -> Bool {
        return lhs.title == rhs.title && lhs.key == rhs.key
    }
}

注意:在此示例中,仅考虑titlekey属性的相等性。即使两个结构具有不同的value属性,它们也可以相等。 hash(into:)函数同样仅考虑titlekey属性。

相关问题