您的位置:首页 > 移动开发 > Objective-C

Objective-C学习-NSSet(集合),NSMutableSet(可变集合) NSCountSet(计数集合)

2015-11-22 17:10 651 查看
NSSet集合对象是用来干什么的呢,在之前做的demo和项目中很少用,但并不是代表不好用,在追求效率方面NSSet要比NSArray要高的多,因为他的查找是通过Hash(哈希)查找,自然会比数组遍历要快的多,而且它不允许里面存在重复的对象,因此多用来去除重复,打个比方例子如下

//创建一个含有重复对象的数组
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]);
}


遍历结果都是:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: