应该都知道,swift的字典key只要实现Hashable协议就都可以做为key使用了(不知道的可以command进去看一下),我主要是介绍一下在我自定义key实现hashable的坑。
- hash值计算的时间复杂度
- 异或运算结果误差
hash值计算的时间复杂度
public protocol Hashable : Equatable {
/// The hash value.
///
/// Hash values are not guaranteed to be equal across different executions of
/// your program. Do not save hash values to use during a future execution.
public var hashValue: Int { get }
}
我们需要返回的hashValue。 返回值Int->对应我们自定义的值类型的hash值
当我们每次去获取dictionary的时候,都会走上面 public var hashValue: Int { get }
闭包
那么我们去读字典的操作时间复杂度=闭包里面的时间复杂度
如果闭包里面有消耗性能的O(n)计算,那访问字典就比较消耗性能了
异或运算结果误差
写放一个我写的例子
struct Account {
var age: Int
var height: Float
}
extension Account: Hashable,Equatable {
var hashValue: Int {
return age.hashValue ^
height.hashValue
}
static func ==(lhs: Account, rhs: Account) -> Bool {
return lhs.age == rhs.age &&
lhs.height == rhs.height
}
}
var account1 = Account(age: 18, height: 180)
一般我们通过异或运算进行一些低消耗的运算。但是我们知道a ^ b是等于b ^ a的,也就是如果Account里面俩个属性的值颠倒过来,那么account1的hash值其实是不变的
算是愚见了,分享出来,希望大家多指点。自己可以多学习!
最后我们一般是尽可能的避免使用引用类型作为key,这通常会给你带来不必要的麻烦。当我们使用引用类型作为key之后,引用类型的对象在Dictionary之外被修改的时候,Key的内容也会随之修改。key对应的哈希值是改变的,这样就无法获得对应的value了。
网友评论