天天看点

Scala集合Scala集合

Scala集合

scala默认采用不可变集合

一、集合概述:

1.Scala的集合有三大类: 序列Seq(有序、线性)、集合set、映射Map(Key->Value),所有的集合都扩展自Iterable特质 2.可变分类 不可变集合(可以安全的并发访问)【scala.collection.mutable】 (1)for循环的1to3生成的是IndexedSeq下的vector (2)String属于IndexSeq (3)Queue和Stack属于LinearSeq (4)IndexSeq通过索引查找定位,速度快 (5)LinearSeq是线性的,有起点和终点,一般通过遍历查找 可变集合【scala.collection.immutable】 可变集合的种类非常多,在Seq中还增加了Buffer(ArrayBuffer、ListBuffer)  

二、数组

1.Array是固定长度数组,ArrayBuffer是不固定长度 2.创建数组赋初值不要使用new关键字,不然是指定创建大小

Scala集合Scala集合
Scala集合Scala集合

3.未赋初值的数组元素都为0 4.用(i)来访问下标为i的元素 5.用for(element<-array)遍历 6.Scala Array对应的是java中的数组,不在Scala集合框架内  

三、元组

1.元组是不同类型值的聚集(所以修改元组内元素的类型一定要给每个元素都指定类型) 2.创建元组

Scala集合Scala集合

3.获取元组内元素(根据下标)

Scala集合Scala集合

4.元组中最多只能有 22个元素  

四、集合

1.主要的集合特质

Scala集合Scala集合

集合三大类:Seq、Set、Map   2.迭代器 内部迭代器:集合或迭代器的拥有者自己遍历集合,使用foreach方法,继承Traversable特质 外部迭代器:Iterable提供了iterator方法,客户代码可以获取迭代器进行自行遍历 Iterable允许只使用集合部分元素的方法,比Traversable更早停止迭代,性能上比后者高。 使用迭代器Iterator(下图)

Scala集合Scala集合

  3.Seq特质(有序、线性) (1)主要是通过length和apply方法定义的,apply方法根据有序序号进行索引操作,length方法返回集合大小。

Scala集合Scala集合

(2)LinearSeq 此特质有3个方法:isEmpty、head、tail 这个特质可以看做是 头元素(head)+tail(除掉头元素以外的 集合)组成的集合(具体看下图例子)

Scala集合Scala集合

(3)IndexSeq 与Seq特质类似,但是可以随机访问,更为高效。   4.Set特质 Set集合代表每个元素都是唯一的。 下面介绍几种set (1)TreeSet 用红黑树实现,红黑树是一种试图保持平衡的数据结构。     它通过检查当前节点来查找树里的元素,如果当前节点大于期望值就查找左树,如果小于期望值就查找右树,正好等 于期望值就找到了正确节点。要想创建一个TreeSet,必须提供隐式的Ordering 类型以便比较大于小于。 拓展:什么是红黑树  https://www.jianshu.com/p/e136ec79235c   (2)HashSet 用 树结构实现集合。最大区别在于 HashSet 用元素的Hash值决定把元素放在哪个节 点上,HashSet 查找时的性能一般好于TreeSet。 (3)BitSet 是用Long 型的序列来实现的,BitSet 通过把其底层Long值与欲保存的整数值位置设置 为true来保存整数,BitSet经常用来在内存里跟踪和保存一大批标志位。   5.Map特质 不可变的Map是有序的,可变的Map是无序的。 Map特质代表键值对的集合,只有有键的值才能存在。Map提供了根据键查找值的高效实现。 Map的用法:

Scala集合Scala集合

应用例子:TreeMap  

五、集合的运算

1.map(元素的映射)和flatten(扁平化) (1)map:将集合中每个元素通过制定函数映射为新的结果集合(一一对应) ①可以作计算操作

Scala集合Scala集合
Scala集合Scala集合

②可以进行字符串的拆解

Scala集合Scala集合
Scala集合Scala集合
Scala集合Scala集合

(2).flatten: 可以通过flatmap和flatten操作将集合中每个元素通过定值函数映射为新的 扁平化结果集合。 关于flatMap和Map的对比和详细描述可以看 下面这篇博文,讲的挺形象的: https://blog.csdn.net/qq_21383435/article/details/77477681   扁平化:简单直接 例子:通过flatten进行元素拼接

Scala集合Scala集合

  2.filter运算 数据筛选操作

Scala集合Scala集合

  3.fold/reduce(折叠/归约操作) (1)reduce 二元操作对集合中的元素进行归约。 reduce包含reduceLeft和reduceRight两种操作,前者从结合的头部开始操作,后者是从尾部开始操作。 例如:求列表的和

Scala集合Scala集合

  (2)fold 折叠(fold)操作和reduce(归约)操作比较类似。fold操作需要从一个初始的“种子”值开始,并以该值作为上下文,处理集合中的每个元素。 Fold包含两个变体foldLeft和foldRight两种操作,foldLeft第一个参数为累计值,集合遍历的方向是从左到右, foldRight第二个参数为累计值,集合遍历的方向是从右到左。

Scala集合Scala集合

4.scan(扫描操作) 扫描,即对某个集合的 所有元素做fold操作,但是会把 产生的所有中间结果放置于一个 集合中保存

Scala集合Scala集合

5.zip(拉链操作,键和值映射起来)  

六、集合分类

1.分类方式: 可变集合和不可变集合 即使计算集合和延时计算集合 顺序计算集合和并行计算集合   下面对集合分类进行举例: 2.不可变集合Vector(后面用到的比较多) (1)Vector是由元素的 下标组成的前缀树, 带索引的不可变序列容器。 如果想要用 链式不可变集合容器,使用 List。 Vector在快速随机访问和快速随机存取方面是比较均衡的,Vectors现在是 immutable indexed sequences的默认实现。 (2)前缀树 每个节点有几个分叉,路径上的数字为几进制。 如0-7的前缀树用二叉树表示:

Scala集合Scala集合

(3)“修改”Vector元素数据 例如:将下标0的位置修改为“new” 因为集合是不可变的,修改指定的下标值会产生新的集合,可以复用前缀树的部分数据。

Scala集合Scala集合

  3.不可变集合List List由两个类组成,一个是代表空列表的Nil,另一个是Cons List是个不可变的单链表,适合在头部的添加和删除操作。 List不适合中间元素的修改,如果修改则前面的元素都要重新生成,不如Vector   4.不可变集合Stream (1)Stream是一种延迟持久(lazy persistent)的集合,也就是说 流可以延迟计算其元素的值。 Stream类似于List,但是最大的区别就是在于Stream会延迟计算。 例子:(其中zip就是链式操作, 注意warning,现在可以用LazyList来代替Stream关键字)

Scala集合Scala集合

(2)Stream(LizyList)构造 List的构造为cons(::) Stream的构造为#:: LazyList.empty表示空流,不是Nil

Scala集合Scala集合

构造了有三个成员的流对象 我们可以看到:在使用到对象的时候才进行创建对象并输出相应的内容,延迟创建   5.可变集合ArrayBuffer 要使用或者创建可变集合必须使用这个包 scala.collection.mutable下的集合。 ArrayBuffer是一种可变数组,其大小与其所含的元素数不一定一致,当添加新元素到 ArrayBuffer时,如果底层数组没有满,则这个元素直接加入到数组,如果底层数组满了,则要创建 更大的数组,把元素都复制到新数组中。ArrayBuffer 对应了 java util 的ArrayList   6.视图(view) Scala集合默认是严格和串行计算的,严格计算是指非延迟计算。 (1)集合库通过两个标准机制来把默认执行方式 转化为 并行计算 或者 延迟计算,分别是 view和par 从Seq[T]通过view方法转化为SeqView[T, ]类型,可以 实现懒操作(延迟计算)。 seqview的官方API https://www.scala-lang.org/api/current/scala/collection/SeqView.html (2)小例子:

Scala集合Scala集合

返回的是集合视图,由返回值可以看到,还没有计算。

Scala集合Scala集合

等价于:

Scala集合Scala集合

  7.并行集合 Scala并行集合是操作并行化的集合。并行集合实现了一种“可拆分”的迭代器

Scala集合Scala集合