这儿每天共享一个 iOS 的新知识,快来重视我吧

前言

数组(Array)和调集(Set)都是调集类型,并且有许多相似之处,可是有意思的是在日常开发中我们一般运用数组,而不是调集。

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

相同点

1、相同的初始化语法糖

初始化一个 Array 和初始化一个 Set 都能够直接经过中括号 [] 进行:

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 函数测验增加目标时,将遇到以下错误:

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

不同点

1、增加目标的方式不同

往数组里增加目标运用 append 函数我们现已很熟悉了,可是往调集里增加函数需要用到 insert 这个函数:

func insert(_ newMember: Element) -> (inserted: Bool, memberAfterInsert: Element)

从这个函数界说上能够看出,它回来一个元组类型,inserted 代表是否刺进成功,memberAfterInsert 代表刺进的这个元素,能够经过这个函数容易判别是否存在相同的元素:

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 是一个 无序调集,不确保元素的方位。

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新知”,每天按时共享一个新知识,这儿只是同步,想要及时学到就来重视我吧!