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

本文详细介绍了Objective-C中的NSSet集合,包括不可变集合NSSet、可变集合NSMutableSet以及计数集合NSCountSet的创建、操作和使用场景。通过对比,突出了NSSet在效率上的优势,特别是在处理重复元素和高效查找方面的应用。文中还通过实例讲解了如何利用NSSet解决数组中不同元素的问题,以及如何进行集合间的交集、差集和并集操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       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]);
    }


遍历结果都是:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值