isEqual与==
UIColor *color1 = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
UIColor *color2 = [UIColor colorWithRed:0.5 green:0.5 blue:0.5 alpha:1.0];
NSLog(@"color1 == color2 = %@", color1 == color2 ? @"YES" : @"NO");
NSLog(@"[color1 isEqual:color2] = %@", [color1 isEqual:color2] ? @"YES" : @"NO");color1 == color2 = NO
[color1 isEqual:color2] = YES==只是简单的用来判断是否是一个对象;isEqual方法用来判断对象是否相同,例如UIColor对象表示的就是color是否相同
如何使用NSSet对系统对象进行去重(NSString、NSDictionary...)
NSMutableSet *mutSet = [NSMutableSet set];
[mutSet addObject:@"123"];
[mutSet addObject:@"1234"];
[mutSet addObject:@"123"];
NSArray *array = mutSet.allObjects;
NSLog(@"%@",array);元素添加进集合的时候会根据hash值、进行isEqual判断对象是否相同,相同的不会再添加进集合。
如何使用NSSet对自定义对象进行去重
对自定义的对象去重,需要重新实现isEqual 和 hash方法,比如一个Person类只要uid相同就认为对象相同
- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}
Person *otherPerson = (Person *)object;
if (self.uid == otherPerson.uid) {
return YES;
}
return NO;
}- (NSUInteger)hash{
return self.uid ^ self.name.hash;
}装入NSSet后进行对象去重:
Person *person1 = [Person new];
person1.name = @"123";
person1.uid = 1;
Person *person2 = [Person new];
person2.name = @"1234";
person2.uid = 2;
Person *person3 = [Person new];
person3.name = @"345";
person3.uid= 1;
NSMutableSet *mutSet = [NSMutableSet set];
[mutSet addObject:person1];
[mutSet addObject:person2];
[mutSet addObject:person3];
NSArray *array = mutSet.allObjects;
NSLog(@"%@",array);打印结果:
"0x60000160e220(2,1234)",
"0x60000160e200(1,123)"重写isEqual应该都理解,为什么要重写- (NSUInteger)hash方法?
先看一下如果不重写- (NSUInteger)hash
打印结果:
"0x6000023d66c0(2,1234)",
"0x6000023d61e0(1,345)",
"0x6000023d6320(1,123)"注意⚠️:一定要多试一下,这个是偶现。
为什么会这样呢?
其实吧NSMutableSet/NSSet,是一个无序集合容器,不像我们上面想的那么简单。
仅仅实现- (BOOL)isEqual:而不实现- (NSUInteger)hash没门。
NSMutableSet/NSSet在数据存储和比较元素相等都和- (NSUInteger)hash方法息息相关。
内部高效滤重机制有- (NSUInteger)hash的很大功劳。为什么重写- (NSUInteger)hash,看到过好几篇文章意思大多是
当前成员的hash值是否和目标hash值相等, 如果相同进行isEqual判断, 如果不等, 直接判断不相等但是我实际实验结果却是两个对象的hash值并不相等,但是却依旧进行isEqual判断,我得出的结论是:
isEqual的调用猜测应该是根据系统底层哈希表的实现来的。并不只是简单的根据hash值是否相等。重写- (NSUInteger)hash:关键属性的hash进行一个简单的 XOR(异或)操作,就能够满足在 99% 的情况下的需求。
return self.uid ^ self.name.hash;总结:
判断自定义对象的是否相同,
1.重写- (BOOL)isEqual:(id)object
2.重写- (NSUInteger)hash