mirror of
https://github.com/NohamR/knowledge-kit.git
synced 2026-05-24 20:00:37 +00:00
35 lines
2.7 KiB
Markdown
35 lines
2.7 KiB
Markdown
# 数组、集合、字典与 hash、isEqual 方法的关联
|
||
|
||
1. NSArray 允许重复添加元素,添加元素的时候不查重,所以不会调用上面2个方法。在移出元素的时候会依次遍历数组内的元素,每个元素调用 **isEqual** 方法(remove 方法传入的元素作为参数),所有返回真值的元素都会被移除。在字典中不涉及 hash 方法。
|
||
|
||
2. NSSet 不允许重复添加元素,所以在添加新元素的时候,该元素的 **hash** 方法会被调用,若集合中不存在与此元素 hash 相同的元素,则它会被直接加入集合,不调用 **isEqual** 方法;若存在,则依次调用该集合每个元素的 **isEqual** 方法,返回真值则判等,不加入,处理结合,若返回 false, 则判定集合内不存在该元素,将其加入。
|
||
|
||
3. 集合中移除元素时,首先调用它的 **hash方法**,若集合中存在与其 **hash值** 相等的元素,则调用该元素的 **isEqual方法**,若返回真值则判断,进行移除;若不存在,则会依次调用集合中每个元素的 **isEqual方法**,只要找到一个返回真值的元素,就进行移除,并结束整个过程(所有这样会有其它满足 isEqual 方法但却漏掉未被删除的元素)。调用 contains 方法时类似
|
||
|
||
4. 因此如果自定义对象被加入到集合或作为字典的 key 时,需要同时重写 isEqual 方法和 hash 方法,这样,若集合存在某元素,则调用它的 contains 和 remove 方法时,可以在 O(1) 完成查询,否则需要 O(n) 完成。
|
||
|
||
5. 需要注意的是,NSDictionary 的 key、value 都说对象类型即可,但是被设为 key 的对象需要遵循 NSCopying 协议。
|
||
|
||
6. hash 方法出现的目的是:当我们从数组中查找元素时,需要依次遍历数组中的元素,时间复杂度为 O(n),为了解决效率问题,引入了 Hash Table 方法。当添加元素的时候,为每个元素设置了 hash 值,这样当下次查找的时候就直接通过 hash 值找到对应的位置,时间复杂度为 O(1)。设计一个合理的 hash 算法的指标是对于每个参数,其返回的 hash 值唯一。
|
||
|
||
7. 查阅资料可知,一个推荐的自定义对象的 **hash** 算法是将关键属性的 hash 值,按照位或运算
|
||
|
||
```
|
||
@interface Person : NSObject
|
||
@property (nonatomic, strong) NSString *name;
|
||
@property (nonatomic, strong) NSDate *birthday;
|
||
@end
|
||
|
||
|
||
- (NSUInteger)hash{
|
||
return [self.name hash] ^ [self.birthday hash];
|
||
}
|
||
```
|
||
|
||
|
||
|
||
8. NSObject 类中的 equal 方法的判断是包括内存地址的,也就是说,NSObject 若想判断2个对象相等,那么这2个对象的内存地址必须相等
|
||
|
||
|
||
|