Set 是一个无序的唯一元素集合,作为哈希表实现。与 Array 的主要区别是没有重复值且没有顺序。主要接口包括:插入方法(insert)、删除方法(remove)、检查存在性的方法(contains)。
运行时间:
insert、remove 和 contains 的平均时间复杂度为 O(1)。使用示例:
var numbers: Set<Int> = [1, 2, 3] numbers.insert(4) // Set: 1, 2, 3, 4 numbers.insert(2) // Set 不会变化,2 已存在 numbers.remove(1) // Set: 2, 3, 4 print(numbers.contains(3)) // true
当唯一性重要而顺序不重要时,请使用 Set。与 Array 比较:
Array 中删除和查找元素的时间复杂度为 O(n)。Array 中允许重复值。Set 支持: ∪、∩、−、⊆、⊇ 及其他集合理论操作。
问题:
以下代码是否会编译,为什么?
let set: Set = [[1, 2], [3, 4]]
答案:
不会编译。Set 要求元素类型符合 Hashable 协议。数组(Array)并没有实现 Hashable,因此无法直接创建数组的集合。例如,Set<Int> 是正确的,而 Set<[Int]> 不是。
故事
在某个服务中,开发人员将对象的唯一标识符存储为 [Int],而不是 Set<Int>。这导致了问题:检查存在性和删除操作运行缓慢(时间 — O(n)),出现重复项,破坏了业务逻辑。
故事
尝试将非标准类型放入 Set(例如,创建了 Set<MyModel>),但该类型没有实现 Hashable。代码只有在添加相应协议后才会编译,但是在实现 hash(into:) 时的错误会导致冲突和不可预测的运行行为。
故事
开发人员期望 Set 中元素的遍历顺序与插入顺序一致,并在相同顺序中构建UI。结果,每次运行时顺序不同,导致最终用户的数据显示不一致。