首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Objective-C NSSet 不可變集合詳解:去重、子集判斷、不可變性

     編輯:關於C語言

Objective-C NSSet 不可變集合詳解:去重、子集判斷、不可變性

NSSet 是 Foundation 框架中的無序唯一集合,對應 Java 的 Set、Python 的 set。本文通過代碼演示其創建、去重特性、衍生新集合、子集/包含判斷等核心操作。

一、核心特性

  • 無序:無索引,遍歷順序不確定
  • 唯一:基於 isEqual: 和 hash 去重
  • 不可變:創建後不能增刪,修改操作返回新集合
  • 可變對應類:NSMutableSet

二、輔助函數:集合轉字符串輸出

// 將 NSArray 或 NSSet 轉為可讀字符串
NSString *NSCollectionToString(id collection) {
    NSMutableString *str = [NSMutableString stringWithString:@"["];
    for (id obj in collection) {
        [str appendString:[obj description]];
        [str appendString:@", "];
    }
    // 移除末尾 ", "
    NSUInteger len = [str length];
    if (len > 1) [str deleteCharactersInRange:NSMakeRange(len - 2, 2)];
    [str appendString:@"]"];
    return str;
}

三、完整代碼演示

#import 

// 前置聲明輔助函數
NSString *NSCollectionToString(id collection);

int main(int argc, const char *argv[]) {
    @autoreleasepool {
        // 1. 創建集合:重複元素 "B" 會自動去重
        NSSet *set1 = [NSSet setWithObjects:@"A", @"B", @"C", @"B", nil];
        NSLog(@"set1 count: %ld", [set1 count]);        // 3
        NSLog(@"set1: %@", NSCollectionToString(set1)); // [A, B, C]
        
        // 2. 不可變性驗證:setByAddingObject 返回新集合
        NSSet *set2 = [set1 setByAddingObject:@"D"];
        NSLog(@"set1 不變: %@", NSCollectionToString(set1)); // [A, B, C]
        NSLog(@"set2 新增: %@", NSCollectionToString(set2)); // [A, B, C, D]
        
        // 3. 子集判斷
        BOOL isSubset = [set1 isSubsetOfSet:set2];
        NSLog(@"set1 ⊆ set2: %d", isSubset); // 1 (YES)
        
        // 4. 包含判斷
        BOOL hasC = [set1 containsObject:@"C"];
        NSLog(@"set1 包含 C: %d", hasC); // 1 (YES)
    }
    return 0;
}

四、運行輸出

2015-12-03 20:16:52.049 NSSetTest[5903:419290] set1 count: 3
2015-12-03 20:16:52.050 NSSetTest[5903:419290] set1: [A, B, C]
2015-12-03 20:16:52.050 NSSetTest[5903:419290] set1 不變: [A, B, C]
2015-12-03 20:16:52.051 NSSetTest[5903:419290] set2: [A, B, C, D]
2015-12-03 20:16:52.051 NSSetTest[5903:419290] set1 ⊆ set2: 1
2015-12-03 20:16:52.051 NSSetTest[5903:419290] set1 包含 C: 1
Program ended with exit code: 0

五、關鍵行為分析

1. 去重機制

setWithObjects: 內部調用 isEqual: 比較對象。對於 NSString,比較內容而非指針,因此 @"B" 只保留一個。

2. 不可變語義

  • setByAddingObject: 不修改原集合,返回新 NSSet 實例
  • 原集合 set1 完全不變,符合函數式編程風格
  • 這也是為什麼 isSubsetOfSet: 返回 YES——set1 確實是 set2 的子集

3. 等價於 Java 對比

六、最佳實踐建議

  1. 需要頻繁增刪時使用 NSMutableSet,配合 addObject:/removeObject:
  2. 自定義對象存入 Set 時,必須同時重寫 isEqual: 和 hash,否則去重失效
  3. 集合間運算(交集/並集/差集)可用 setByAddingObjectsFromSet:、intersectSet: 等方法
  4. 性能敏感場景考慮 NSSet 而非 NSArray 做查找(O(1) vs O(n))

七、總結

NSSet 以不可變、去重、高效查找為核心特性,是處理唯一性集合的首選。理解其「修改返回新對象」的函數式語義,配合 NSMutableSet 靈活切換,能編寫更安全、可預測的代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
操作Objective-C (NSSet)Java (HashSet)
創建[NSSet setWithObjects:...]new HashSet<>(Arrays.asList(...))
添加元素[set setByAddingObject:obj] (返回新)set.add(obj) (原地修改)
判斷包含[set containsObject:obj]set.contains(obj)
子集判斷[set1 isSubsetOfSet:set2]set2.containsAll(set1)
遍歷for (id obj in set)for (Object obj : set)