一、同等性判断
1.“==”
(1)对于对象类型,“==” 比较的是对象的地址,即是否为同一个对象
NSString *str = @"test1";
NSString *strCopy = [str copy];
NSString *strNew = [NSString stringWithFormat:@"test%@", @1];
BOOL equalA = (str == strCopy); // YES
BOOL equalB = (str == strNew); // NO
(2)对于基本类型,“==”比较的是值
NSInteger x = 123;
NSInteger y = 123;
NSInteger z = 1234;
BOOL equal0 = (x == y); // YES
BOOL equal1 = (x == z); // NO
2.isEqual
(1) isEqual:NSObject 协议中声明的方法来判断两个对象的等同性,可直接使用
NSString *str = @"test1";
NSString *strNew = [NSString stringWithFormat:@"test%@", @1];
BOOL equalD = [str isEqual:strNew]; // YES
(2)iOS系统已经实现了部分NSObject子类的isEqual方法,可直接使用
NSString - isEqualToString
NSArray - isEqualToArray
NSDictionary - isEqualToDictionary
NSSet - isEqualToSet
(3)对于自定义的类型来说,需要重写isEqual方法:
//重写系统的isEqual
- (BOOL)isEqual:(id)object {
//Step 1: ==运算符判断是否是同一对象, 因为同一对象必然完全相同
if (self == object) {
return YES;
}
//Step 2: 判断是否是同一类型, 这样不仅可以提高判断的效率, 还可以避免隐式类型转换带来的潜在风险
if (![object isKindOfClass:[Person class]]) {
return NO;
}
//Step 3: 通过封装的isEqualToPerson方法, 提高代码复用性
return [self isEqualToPerson:(Person *)object];
}
//自定义方法来执行有意义的值比较
- (BOOL)isEqualToPerson:(Person *)person {
//Step 4: 判断person是否是nil, 做参数有效性检查
if (!person) {
return NO;
}
//Step 5: 对各个属性分别使用默认判等方法进行判断
BOOL haveEqualNames = (!self.name && !person.name) || [self.name isEqualToString:person.name];
BOOL haveEqualBirthdays = (!self.birthday && !person.birthday) || [self.birthday isEqualToDate:person.birthday];
//Step 6: 返回所有属性判等的与结果
return haveEqualNames && haveEqualBirthdays;
}
(4)isEqual和hash的联系:如果 isEqual: 方法判断两个对象相等,那么其 hash 方法必须返回同一个值
3.hash
(1)哈希表:hash表是一种特殊的数据结构,能够快速定位到想要查找的记录
在数组中查找某个成员
- 遍历数组中的成员
- 将取出的值与目标值比较, 如果相等, 则返回该成员
使用hash
- 通过hash值直接找到查找目标的位置
- 如果目标位置上有多个相同hash值得成员, 此时再按照数组方式进行查找
结论:若是无多个相同hash值的成员,使用hash查找较快
(2)hash方法什么时候被调用:
//对象被添加至NSSet
[set1 addObject:person1];
// 设置为NSDictionary的key
[dictionaryValue2 setObject:person2 forKey:kKey2];
(3)hash方法与isEqual的关系:hash值是对象判断的必要非充分条件
1.先判断hash是否相等,如果不相等则直接判定,如果相等,则进入第二步
2.重写isEqual方法
(4)在项目中的具体使用:重写hash方法
- (NSUInteger)hash {
return [self.name hash] ^ [self.birthday hash];
// NSObject的hash值是调用hash方法的对象地址,一般不用,需要重写一个hash的方法实现
//return [super hash];
}
二、 深度同等行判断
比较两个数组是否相等的话可以使用深度同等性判断方法:
1.先比较数组的个数
2.再比较两个数组对应位置上的对象均相等。
要点:
- 若想检测对象的等同性,请提供“ isEqual:” 与 hash 方法。
- 相同的对象必须具有相同的哈希码,但是两个哈希码相同的对象却未必相同。
- 不要盲目地逐个检测每条属性,而是应该依照具体需求来制定检测方案。
- 编写hash方法时,应该使用计算速度快而且哈希码碰撞几率低的算法。