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新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
鸿蒙布道师11 小时前
鸿蒙NEXT开发资源工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
season_zhu13 小时前
iOS开发:关于路由
ios·架构·swift
鸿蒙布道师16 小时前
鸿蒙NEXT开发设备相关工具类(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
熊猫鹏-梓潼18 小时前
Swift Programming All in One苹果程序开发自学之路
开发语言·ios·swift
njsgcs1 天前
用swift playground写个ios应用和大模型或者网站交互
ios·swift
Swift社区1 天前
从表格到序列:Swift 如何优雅地解 LeetCode 251 展开二维向量
开发语言·leetcode·swift
leluckys1 天前
swift-11-init、deinit、可选链、协议、元类型
开发语言·ios·swift
njsgcs1 天前
vscode swift hello world
开发语言·ios·swift
YungFan1 天前
SwiftUI-MLX本地大模型开发(三)
ios·llm·swiftui
请叫我飞哥@2 天前
Apple ID授权登入
ios·swiftui