Objective-C学习-NSSet(集合),NSMutableSet(可变集合) NSCountSet(计数集合)
2015-11-22 17:10
651 查看
NSSet集合对象是用来干什么的呢,在之前做的demo和项目中很少用,但并不是代表不好用,在追求效率方面NSSet要比NSArray要高的多,因为他的查找是通过Hash(哈希)查找,自然会比数组遍历要快的多,而且它不允许里面存在重复的对象,因此多用来去除重复,打个比方例子如下
为什么楼主会想写这么一篇介绍NSSet的文章,是之前只是了解了一下这个类以及作用,但最近遇到一个面试题,就是说通过面向对象的思维处理两个数组,将两个数组里面不同的数字取出来
当然最一般的就是通过两个for循环,但是通过for循环遍历两个数组来判定的时间复杂度为O(n^2),如果有4个数组,并且每个数组中有100000个元素呢,那么这种算法很明显会很差劲,而且这样算是面向过程的,而且这样做绝对不是最优算法,在objc中去除重复首先必然会想到一个类,就是NSSet,先来看看解决方案如何
上面的有关方法可能不太好理解的就那么几个,那么下面就来解释一下集合类(NSSet)
相关属性如下:
首先创建两组测试对象
遍历结果都是:
//创建一个含有重复对象的数组 NSArray * test1 = @[@1,@1,@1,@4,@5]; //通过转换数组来创建集合(NSSet)对象 testSet1 NSSet * testSet1 = [NSSet setWithArray:test1];//此时testSet1 = {(@5,@1,@4)}
为什么楼主会想写这么一篇介绍NSSet的文章,是之前只是了解了一下这个类以及作用,但最近遇到一个面试题,就是说通过面向对象的思维处理两个数组,将两个数组里面不同的数字取出来
当然最一般的就是通过两个for循环,但是通过for循环遍历两个数组来判定的时间复杂度为O(n^2),如果有4个数组,并且每个数组中有100000个元素呢,那么这种算法很明显会很差劲,而且这样算是面向过程的,而且这样做绝对不是最优算法,在objc中去除重复首先必然会想到一个类,就是NSSet,先来看看解决方案如何
NSArray * array1 = @[@1,@2,@3,@4]; NSArray * array2 = @[@2,@3,@4,@5]; //根据数组实例化两个集合对象 NSSet * set1 = [NSSet setWithArray:array1]; NSSet * set2 = [NSSet setWithArray:array2]; //根据集合对象创建两个可变集合对象 NSMutableSet * set3 = [NSMutableSet setWithSet:set1]; NSMutableSet * set4 = [NSMutableSet setWithSet:set2]; //调用方法,表示在前者的 集合set对象中 消除 后者集合set对象 中存在的元素 [set3 minusSet:set2];//此时set3 = {(@1)} [set4 minusSet:set1];//此时set4 = {(@5)} NSMutableSet * set5 = [NSMutableSet set]; //表示在 set5对象中 添加 set3中存在并且set5中不存在的 元素 [set5 unionSet:set3];//此时set5 = {(@1)} [set5 unionSet:set4];//此时set5 = {(@1,@5)} //获得set对象中的所有元素 NSArray * array = [set5 allObjects];//array = @[@1,@5]
上面的有关方法可能不太好理解的就那么几个,那么下面就来解释一下集合类(NSSet)
NSSet_不可变集合
不可变的集合即表示一旦创建好之后,不允许发生变化,与NSArray,NSDictionary,NSString相似,但是查找效率会比数组高的多创建方法:
/*关于 集合NSSet 的相关创建方法*/ //通过最基础的方法创建对象(第一种是最简单的创建方法,第二种是便利构造器创建,第三种是其他语言创建对象的形式,objc也兼容) NSSet * s1 = [[NSSet alloc]init]; NSSet * s2 = [NSSet set]; NSSet * s3 = [NSSet new]; //通过 转换数组 将数组的元素转换成集合 NSSet的元素 NSSet * s4 = [[NSSet alloc]initWithArray:@[@1,@2,@3]]; NSSet * s6 = [NSSet setWithArray:@[@1,@2,@3]]; //通过 直接定义元素 来创建集合 NSSet * s7 = [[NSSet alloc]initWithObjects:@1,@2,@3,nil]; NSSet * s8 = [NSSet setWithObjects:@1,@2,@3,nil]; //通过 其他的集合对象 创建集合对象 NSSet * s9 = [[NSSet alloc]initWithSet:set6]; NSSet * s10 = [NSSet setWithSet:set6];
相关属性:
首先创建两个测试的NSSet对象//测试用的集合Set NSSet * set6 = [NSSet setWithArray:@[@1,@2,@7]]; NSSet * set7 = [NSSet setWithArray:@[@1,@2,@3]];
相关属性如下:
//集合(NSSet的元素个数) NSInteger count = set6.count;//count= 3 //表示从set6 中取出 @1 这个对象(如果存在返回@!,不存在返回nil) NSNumber * n1 = [set6 member:@1];//返回@1 NSNumber * n2 = [set6 member:@71];//返回nil //获取 set5集合元素 的枚举器 NSEnumerator * enumerator = [set6 objectEnumerator]; //遍历枚举器 NSNumber * n3; while ( n3 = [enumerator nextObject]) { //coding //打印的话 能将n3 全部打印出来,顺序不一定,因为是按照哈希查找,查找速度比数据以及字典要快 //结果:@7,@1,@2 NSLog(@"n3 = %@",n3); } //获取集合 set5 中的一个对象,并且不保证是随机的,测试打印是 n4 = 1 NSNumber * n4 = [set6 anyObject]; NSLog(@"n4 = %@",n1);
相关判断方法:
//表示set6 中是否至少有一个元素 也存在与set7 //结果:b1 = YES BOOL b1 = [set6 intersectsSet:set7]; //表示set6 与 set7 是否相同 //结果:b2 = NO BOOL b2 = [set6 isEqualToSet:set7]; //表示set6 中所有的元素是否 都存在于set7 //结果:b3 = NO BOOL b3 = [set6 isSubsetOfSet:set7]; //表示set6 中是否存在 7(NSNumer类型)的对象 //结果:b4 = YES BOOL b4 = [set6 containsObject:@7];
相关操作:
//表示 set8 为 集合对象set6 通过转换数组 追加的数组中的元素 后的集合 //结果:set8 = {(@7,@10,@111,@2,@1)} 顺序不一定是原来定义的顺序 NSSet * set8 = [set6 setByAddingObjectsFromArray:@[@10,@111]]; //表示 set9 为 集合对象set6 通过转换集合 追加集合中的元素 后的集合 //结果:set9 = {(@7,@3,@2,@1)} 顺序不一定是原来定义的顺序 NSSet * set9 = [set6 setByAddingObjectsFromSet:set7]; //表示 set10 为 集合对象set6 添加一个 NSNumber类型的对象 后的集合 //结果:set10 = {(@7,@2,@1111,@1)} 顺序不一定是原来定义的顺序 NSSet * set10 = [set6 setByAddingObject:@1111];
NSMutableSet_可变集合
因为可变集合(NSMutableSet)是继承于不可变集合(NSSet),所以创建方法都是试用的,那么下面只说明特有的方法即可首先创建两组测试对象
//创建测试的NSMutableSet对象 NSMutableSet * set11 = [NSMutableSet setWithArray:@[@1,@10,@100,@79]]; NSMutableSet * set12 = [NSMutableSet setWithArray:@[@1,@100,@89]];
添加元素
//为set11 添加一个 NSString 类型 value = "RunIntoLove" 的元素 //结果:set11 = {(@1,@10,@100,@79,@"RunIntoLove")} 顺序不一定一样 [set11 addObject:@"RunIntoLove"]; //为set11 添加一个 NSArray 类型,通过对NSArray元素的转换 添加到set对象中 //结果:set11 = {(@1,@10,@100,@79,@"RunIntoLove",@"Yue",@"Wen")} 顺序不一定一样 [set11 addObjectsFromArray:@[@"Yue",@"Wen"]];
删除元素
//为set11 删除一个 @“Wen”的对象 //结果:set11 = {(@1,@10,@100,@79,@"RunIntoLove",@"Yue")} //这里如果要删除的对象不存在 也不会报错 找不到的时候就不会进行操作 [set11 removeObject:@"Wen"]; //删除set11 中所有的元素 //结果:set11 = {()} [set11 removeAllObjects];
集合求交集
//表示从 set11 中删除 set12 中没有的对象 //结果:set11 = {(@100,@1)} [set11 intersectSet:set12];
集合求差集
//表示从 set11 中删除 set12 中有的对象 //结果:set11 = {(@79,@10,@"Yue",@"RunIntoLove")} [set11 minusSet:set12];
集合求并集
//表示 将set12中有而set11中没有的对象 添加到set11 //结果:set11 = {(@100,@79,@10,@"Yue",@1,@"RunIntoLove",@89)} [set11 unionSet:set12];
赋值
//表示 将set12中的对象全部赋值到 set11 ,之前会清除set11 中所有的元素 //结果:set12 = {(@100,@1,@89)} [set11 setSet:set12];
NSCountSet_计数集合
什么叫做计数集合呢,NSCountSet是继承于NSMutableSet的类,NSSet是不能存在两个相同的对象的,那么遇到重复它会直接丢掉吗,不是的,它会存在一个计数器,当存在重复的,那么重复的元素的计数器就会+1,通常可以用来元素的个数创建对象
//通过数组创建的NSCountedSet类对象 NSCountedSet * countSet = [NSCountedSet setWithArray:@[@1,@1,@2,@2,@2,@3]]; //通过以上的集合Set11创建NSCountSet类对象 NSCountedSet * countSet11 = [NSCountedSet setWithSet:set11];
增加元素
//可以添加元素 [countSet addObject:@"RunIntoLove"];
删除元素
//可以删除元素 [countSet removeObject:@"RunIntoLove"];
统计元素出现的次数
通过API获取 NSEnumerator 枚举器
//统计所有的元素以及出现次数 //可以通过API中提供的枚举器遍历 NSEnumerator * enumerator1 = [countSet objectEnumerator]; id object; while (object = [enumerator1 nextObject]) { NSLog(@"我是%@,与我相同的个数是:%ld",object,[countSet countForObject:object]); }
通过获得所有的元素进行遍历
//也可以通过数组来遍历 //因为继承于NSMutableSet,所以NSSet的属性也是可以用的 //获取里面存的所有的对象 //结果:countSetObjects = [@3,@2,@1] NSArray * countSetObjects = [countSet allObjects]; for (id object in countSetObjects) { NSLog(@"我是%@,与我相同的个数是:%ld",object,[countSet countForObject:object]); }
遍历结果都是:
相关文章推荐
- Objective-C:神在细节之中
- Objective-C Associated Objects 的实现原理
- Objective-C 的动态提示和技巧
- Core Data浅谈系列之三 : 了解NSManagedObject和NSPredicate(附Demo)
- 问题1 String类和Object类中的equals方法比较
- 【转载】Animation 动画(三)ObjectAnimator、valueAnimator
- Objective-C 中的元类(meta class)
- [iOS]Objective-C的语言版本,与Xcode版本有对应关系吗?
- IOS开发基础Object-C(08)—OC内存管理(2)-对象之间的内存管理
- OC中的枚举
- Ry’s Objective-C Tutorial → Data Types---Date Programming
- Ry’s Objective-C Tutorial → Data Types---NSDictionary
- Ry’s Objective-C Tutorial → Data Types---NSArray
- Ry’s Objective-C Tutorial → Data Types---NSSet
- Ry’s Objective-C Tutorial → Data Types---NSString
- Ry’s Objective-C Tutorial → Data Types---NSDecimalNumber
- Ry’s Objective-C Tutorial → Data Types---NSNumber
- Ry’s Objective-C Tutorial → Data Types---C Primitives
- Ry’s Objective-C Tutorial---Objective-C Data Types
- Ry’s Objective-C Tutorial---Memory Management