GeekBand.Swift-集合类型

2016/5/18 posted in  iOS学习笔记  

数组(Array)

数组是一个有序的元素序列,支持随机存储,支持动态更新长度。
索引从0开始,依次递增。索引访问越界时会抛出异常。
在Swift中,Array被定义为Struct类型,值类型,拷贝时具有值语义。但是,它内部却包含一个指向堆上的元素指针。其指向真正存放的数组元素。

内存模型

使用数组

数组支持变量或常量。常量数组的长度和元素内容都不能更改。

//数组声明与实例化
var array1=[1,2,3,4,5];
var array2:[Int];
var array3:Array<Int>;
array2=[Int](count:10, repeatedValue:10);
array3=[Int]();

//变量数组和常量数组
var array5=[1,2,3]
let array6=[1,2,3]

数组遍历

  • 使用for循环访问array需要检查索引是否越界。具有性能代价。
  • 尽可能使用for-in来遍历数组元素;或者使用Array.enumerate()遍历索引;二者在编译器层面会优化掉索引检查。
for item in array5{
    print(item);
}

for(index, value) in array5.enumerate(){
    print("\(index): \(value)");
}

for index in 0..<array5.count {
    print(array5[index]);
}

缓存容量与增长

  • 数组初始化后,会分配一个缓存容量capacity,其长度一般大于实际的元素数量
  • 当数组长度增长时,如果实际需求大于capacity,其capacity会以近似二倍的方式指数增长,产生对应代价:
    • 分配新的堆内存 2*capacity
    • 将原来堆内存上的元素拷贝到新内存
    • 释放原来的内存
  • 最佳实践:估计好capacity,预先分配好一定的容量。避免频繁造成capacity的增长。

copy-on-write共享技术

同一个数组拷贝到不同的变量中时,其指向堆的元素指针不变。即不同的变量共享一份内存空间,从而节省内存开销。
但是,当某一个变量的元素内容发生改变时,先将原来的堆内存拷贝一份,元素指针指向新的拷贝,然后再更改新的拷贝,从而确保正确性。
copy-on-write的目的是实现“元素内容相同的数组共享内存,同时支持元素的随时修改”
更改前:

更改后:

集合类型(Set)

Set是一个无序集合,其存储的值不能重复。
Set中的值必须有哈希值,即支持Hashable协议。
Set被定义为Struct,值类型,与Array类似。

var set = Set<String>();
var set2:Set<String>;
set2 = ["shanghai","beijing"];

字典类型(Dictionary)

Dictionary是一个存储Key—Value的无序的集合,key唯一,value可重复。
Dictionary中的Key必须支持Hashable协议。
Dictionary被定义为Struct,值类型,特征与Array一致。

var dictionary1 = [String:Int]();
var dictionary2 : Dictionary<String,Int>;
dictionary2=["Jason":36, "Tom":31, "Marty":44];

for(name, age) in dictionary2{
    print("The Age of \(name) is: \(age)")
}