编程iOS开发者

在Swift中,Set数据类型的特点、接口、操作的运行时间以及使用中的潜在问题,与数组(Array)的区别。

用 Hintsage AI 助手通过面试

答案

Set 是一个无序的唯一元素集合,作为哈希表实现。与 Array 的主要区别是没有重复值且没有顺序。主要接口包括:插入方法(insert)、删除方法(remove)、检查存在性的方法(contains)。

运行时间:

  • 操作 insertremovecontains 的平均时间复杂度为 O(1)。
  • 遍历所有元素的时间复杂度为 O(n)。

使用示例:

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。结果,每次运行时顺序不同,导致最终用户的数据显示不一致。