swift 基础:探究 Array 和 Set 的区别

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

数组(Array)和集合(Set)都是集合类型,并且有很多相似之处,但是有意思的是在日常开发中我们通常使用数组,而不是集合。

在面试中,也经常被问到两者的异同,今天来讲讲这两个类型的区别。

相同点

1、相同的初始化语法糖

初始化一个 Array 和初始化一个 Set 都可以直接通过中括号 \[\] 进行:

sql 复制代码
let array: Array<Int> = [1, 2, 3, 4, 5]
let set: Set<Int> = [1, 2, 3, 4, 5]

这是因为它们都实现了 ExpressibleByArrayLiteral 协议,如果不声明类型为 Set<Int>,默认情况下它将生成一个数组。

2、都是值类型

数组和集合都是值类型。如果使用 let 定义 Set,那么当使用 insert 函数尝试添加对象时,将遇到以下错误:

不同点

1、添加对象的方式不同

往数组里添加对象使用 append 函数我们已经很熟悉了,但是往集合里添加函数需要用到 insert 这个函数:

swift 复制代码
func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element)

从这个函数定义上可以看出,它返回一个元组类型,inserted 代表是否插入成功,memberAfterInsert 代表插入的这个元素,可以通过这个函数轻易判断是否存在相同的元素:

swift 复制代码
var set: Set<Int> = [1, 2, 3, 4, 5]
let (inserted, memberAfterInsert) = set.insert(2)
if inserted {
    print("\(memberAfterInsert) 插入成功!")
} else {
    print("集合中已经存在元素 \(memberAfterInsert),插入失败!")
}

2、Set 中的元素不能重复

这是集合和数组之间的一个最大的区别,元素的唯一性。数组可以包含多个相同的值,而集合永远不会包含重复项。这也是上面的 insert(_:) 方法返回一个布尔值来表示插入是否真正成功的原因。

正因为这个特性,集合也经常用来为数组做去重操作

3、元素的顺序不同

数组会保证元素的顺序,先 append 的在前面,后 append 的在后面,也可以通过 insert(_: at:) 方法来把元素插入到固定的位置。

但是 Set 是一个 无序集合,不保证元素的位置。

sql 复制代码
var array: Array<Int> = [1, 2, 3, 4, 5]
var set: Set<Int> = [1, 2, 3, 4, 5]
print(array, set)

上边的代码打印:1, 2, 3, 4, 5 4, 2, 5, 3, 1,不管运行多少次,array 的元素顺序总是固定的,而 Set 的元素可能每次执行的结果都不一样。

因此,如果元素的顺序对你的需求很重要,你应该选择数组。

4、子元素类型略有不同

ArraySet 的子元素类型都是范型,但是 Set 要求子元素必须实现 Hashable 协议(可哈希),而 Array 对子元素没有要求。

标准库中的大多数类型(字符串、数字、Bool)都是可哈希的。

但如果是自定义的类型,就需要先遵守 Hashable 协议才能存进 Set 中,Set 底层也是根据 Hashable 中的 hashValue 值来去重的。

性能方面比较

ArraySet 在 Swift 中都是通过泛型和协议来实现的。

在底层,Array 使用连续内存存储元素,这也保证了它的元素顺序是固定的。连续的内存空间也使得访问元素时速度快,但插入和删除元素可能需要移动其他元素,导致性能下降。

Set 则使用哈希表进行存储(跟字典原理相同),存储的内存是不连续的,哈希表好处是查找、添加、删除操作速度都很快(平均时间复杂度为O(1)),但坏处是会消耗更多内存。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
代码的小搬运工12 小时前
KVO学习
学习·ios·cocoa
方白羽12 小时前
为什么 Android 非要用 Intent 传值?
android·ios·harmonyos
dora13 小时前
iOS开发新手的第一行代码
ios
用户380341658829720 小时前
视频编辑器的滤镜图内核:Node/Pin 模型怎么设计,撤销重做怎么才不崩
ios
CocoaKier1 天前
苹果续费成功,几天后付费协议突然失效,导致线上苹果支付全部失败
ios·apple
刘广睿2 天前
素材库智能集合怎么设计?把多维筛选存成动态收藏的功能复盘
客户端·架构设计·产品设计·素材管理
深念Y2 天前
PVE 安装黑苹果并直通 Quadro P400
macos·ios·黑苹果·驱动·苹果·英伟达·p400
weixin-a153003083162 天前
7.Appium-ios端自动化
ios·appium·自动化
Anhty2 天前
2026九月最新变声器测评:iOS安卓双端适配,低延迟运行更稳定
android·人工智能·功能测试·ios·智能手机
_瑞3 天前
APM_OOMDetector
ios