集合

第4章 集合

Scala集合同时支持不可变集合和可变集合,不可变集合可以安全的并发访问
不可变集合:scala.collection.immutable
可变集合:scala.collection.mutable

Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和非可变(immutable)的版本。

Scala的集合有三大类:序列Seq(有序、线性)、集Set、映射Map(Key->Value),所有的集合都扩展自Iterable特质。

Iterable是指那些能生成用来访问集合中元素的 Iterator 的集合

用for(element<- array)来遍历内容

不可变集合继承层次:

Scala 数组和 Java 数组互操作,Scala Array 对应的是java 中的数组,不在Scala 集合框架层次之内
List属于Seq,因此和java的List不是同一概念。
For循环的1 to 3生成的是IndexedSeq下的Vector。
String属于IndexSeq。
Queue和Stack属于LinearSeq。
IndexSeq通过索引查找定位,速度快。
LinearSeq是线性的,有头尾概念,一般通过遍历查找。

image-20200113114126763

可变集合继承层次

可变集合更加丰富。
Seq中增加了Buffer(ArrayBuffer、ListBuffer)
其他参考不可变集合

image-20200113114234134

迭代器(Iterator)

Scala 提供了外部的或内部的迭代器。内部迭代器是由集合或者迭代器的拥有者自己遍历集合;外部迭代器是由外部调用者决定迭代的结束。
Traversable特质提供了 foreach 方法,foreach 方法是个内部迭代器,接收一个函数作为参数,对集合每个元素应用该函数。
Iterable 提供了 iterator 方法,客户代码可以获取迭代器自行遍历。

内部迭代器是由集合或者迭代器的拥有者自己遍历集合
重写foreach 方法需要考虑一个问题,不管对集合做什么操作,整个文件都将会被遍历

image-20200113120200081

外部迭代器:Iterable特质提供了iterator方法,iterator 方法返回了一个能用来遍历集合元素的外部迭代器
Iterable 允许只使用集合部分元素的方法,比Traversable 更早提前停止迭代,从而性能上比Traversable稍稍提高。

image-20200113120318545

4.1 序列(Seq)

序列(seq)-有序、线性。

Seq 特质是通过length 和 apply 方法来定义的,Seq 代表连续有序,apply 方法能根据有序序号进行索引操作,length 方法返回集合大小。

Seq 可以用于采样数据,比如音频数据,音频数据以采样率的形式记录,其记录顺序对于数据处理是及其重要的。Seq 特质允许我们计算其滑动窗口。

val x = Seq(2, 1, 30, -20, 1, 2, 0)

LinearSeq 特质代表能够分割为头元素+尾集合的集合,这个特质通过三个“假定高效”的抽象方法来定义的: isEmpty , head , tails
注:可以用 LinearSeq 模拟栈(Stack:拿栈顶的元素很容易,但是要拿底下的就很难)

IndexedSeq 特质与Seq 特质类似,只是 IndexedSeq 随机访问更为高效

4.2 集(Set)

Set 集合类型代表一种其每个元素都是唯一的集合、至少对==方法来说是唯一。
Scala 支持三种不可变和可变Set: TreeSet, HashSet, BitSet

TreeSet用红黑树实现,红黑树是一种试图保持平衡的数据结构。
它通过检查当前节点来查找树里的元素,如果当前节点大于期望值就查找左树,如果小于期望值就查找右树,正好等于期望值就找到了正确节点。要想创建一个TreeSet,必须提供隐式的Ordering 类型以便比较大于小于。

HashSet 用树结构实现集合。最大区别在于 HashSet 用元素的Hash值决定把元素放在哪个节点上,HashSet 查找时的性能一般好于TreeSet。

4.3 映射(Map)

不可变的Map是有序的,可变的Map是无序的。

Map特质代表键值对的集合,只有有键的值才能存在。Map提供了根据键查找值的高效实现。
Map 能从键类型到值类型的偏函数(partial function)
Map 提供了当值不存在时,返回默认值的能力

->操作符用来创建对偶(键值对)

val scores = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)

()表示法用来查找某个键对应的值,如果不包含请求的键将会抛出异常

val BOBsScore = scores("Bob")

contains方法:检查映射中是否有某个指定的值

val a = if (scores.contains("Bob")) scores("Bob") else 0val a = scores.getOrElse("Bob", 0)

TreeMap

image-20200113121142827

更新映射中的值(映射是可变的)

= 更新或添加值

scores("Bob") = 10 //如果该映射中没有该键,则添加该键;否则修改该键对应的值

+= 添加多个对偶

-+ 移除多个对偶

迭代映射

for((k, v) <- 映射) 处理k和v

for((k, v) <- 映射) yield (v, k) 交换键值的位置

posted @   昵称已经被使用  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示