加深理解代替单纯记忆
iOS中,hash一般用于字典(Dictionary)、集合(Set)数据结构的key
- 字典和集合为了高效获取数据,底层使用哈希表进行存储
- 所以对于字典和集合的key来说,必须有对应的哈希算法,计算出哈希值,通过哈希值找到最终value
- 所以真正的查数据过程是
key -> hashvalue -> value - 哈希算法(函数)要求:
- 两个相等的key,那么它计算出的哈希值一定要相同。否则,相同的key找到不同的value是不允许的
- 两个不相等的key,计算的hashvalue也应该不同
- 但真实情况下,两个不同的key的哈希值也可能相同,很难做到完全不同
- 这种情况我们就叫做哈希算法(函数)出现了冲突,或者哈希碰撞
- 有一些可以降低冲突问题的办法,本文不展开说了就
- 另一问题是,在读取value时如果真的冲突了,也不能让返回的value是错误的,所以这里要提到
isEqual方法了- 比如在底层哈希结构中,key1对应着value1,key2对应着value2
- 查找key1对应的value1时,发现key1和key2的哈希值一样,那有可能找到了value2
- 为了保证找到正确的value1,此时会先查看value2对应的key,发现是key2,然后用key2与开始查找时的key(也就是key1)通过
isEqual方法作对比,发现key1!=key2,所以找到的value2是不对的。需要继续查找
- 那么这个哈希算法在iOS的字典和集合中,是需要我们自己实现的,下面看下OC和Swit中不同的实现
hash in NSObject Protocol
@property(readonly) NSUInteger hash;
hash方法就是Objective-C中所用的哈希算法NSObject类实现了该方法,默认实现是返回对象的内存地址
另外,
NSObject有一个hash的类方法,暂不清楚用来干啥
Objective-C中如何选择哈希算法
Equality一文中建议,对需要参与哈希运算的参数,使用异或运算获得哈希值
- (NSUInteger)hash {
return [self.red hash] ^ [self.green hash] ^ [self.blue hash];
}
Hashable Protocol in Swift
该协议进一步简化了哈希算法的编写难度,该协议的核心方法是:
func hash(into hasher: inout Hasher)
使用者只对每个参与哈希的参数调用Hasher的combine方法,即可生成合适的哈希值
func hash(into hasher: inout Hasher) {
hasher.combine(text)
hasher.combine(width)
hasher.combine(textColor)
}
Hashable协议继承自Equatable协议,所以需要实现==方法