Scala集合笔记

Scala集合笔记

Scala集合

  1. 可变集合
  2. 不可变集合(可以安全地并发访问)
  • 默认都是不可变集合,Scala集合都提供了可变和不可变的版本
  • Scala的集合有三大类:序列Seq(有序、线性)、集Set、映射Map(Key->Value,都实现了iterable特质
  • Scala 数组和java 数组可以互操作

遍历集合元素

for(element<-array)

在这里插入图片描述

scala数组

  • 长度固定则使用Array,不固定则使用 ArrayBuffer

  • 提供初始值时不使用new

    • Array(100):含有元素100的长度为1的数组
    • new Array(100):长度为100的数组
  • [Any]泛型表示该数组可以存放任意类型。

  • 在没有赋值的情况下,各个元素值为0。

  • 用(i)来访问下标为i 的元素

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

  • Scala 数组和 Java 数组互操作,Scala Array 对应的是java 中的数组,不在Scala 集合框架层 次之内

  • array++:list 把list加到array尾部

  • ++= 可以追加任何一个集合

  • 多维数组

    • // 定义2行3列的多维数组
      val d = Array.ofDim[Int](2,3)
      

元组

  • 元组是不同类型值的聚集 (1,3.14,“Fred”)
  • 定义元组的方式
  • 元组中最大只能有22个元素
  • 获取元组方式,元组._1
  • 试图通过一个类型参数来限定元组中所有 的元素的类型是错误的,需要单独限制,或者不限制

集合

  • 集合三大类,序列、集合和映射
  • 所有集合都扩展自Iterable 特质
  • Iterable是指那些能生成用来访问集合中元素的 Iterator 的集合

Scala 提供了外部的或内部的迭代器。内部迭代器是由集合或者迭代器的拥有者自己遍历集合 ;外部迭代器是由外部调用者决定迭代的结束。

list(1 to 10:_*)	\\扁平化 \\Cons(1,Cons(2,Cons(3,Cons(4,Cons(5,Cons(6,Cons(7,Cons(8,Cons(9,Cons(10,Nil))))))))))
list(1 to 10)\\Cons(Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),Nil)

集合运算

++: 合并
--: 去除公共元素
&: 交
| :并
&~:差

外部迭代器

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

Seq

  • 序列有序,线性
  • 可用于采样数据,计算滑动窗口

LinearSeq and IndexedSeq

LinearSeq特质代表能够分割为头元素+尾集合的集合,这个特质通过三个“假定高效”的抽 象方法来定义的: isEmpty , head , tail

indexedSeq与seq类似但随机访问效率高

Set

Set中每个元素都是唯一的

scala支持三种可变和不可变的set,分别是

  1. treeSet

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

  2. HashSet

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

  3. BitSet
    用Long 型的序列来实现的,BitSet 通过把其底层Long值与欲保存的整数值位置设置为true来保存整数,BitSet经常用来在内存里跟踪和保存一大批标志位。
    BitSet是位操作的对象,值只有0或1即false和true,内部维护了一个long数组,初始只有一个long,所 以BitSet最小的size是64,当随着存储的元素越来越多,BitSet内部会动态扩充,最终内部是由N个long来存 储,这些针对操作都是透明的。用1位来表示一个数据是否出现过,0为没有出现过,1表示出现过。使用用的 时候既可根据某一个是否为0表示,此数是否出现过。 一个1G的空间,有 8102410241024=8.5810^9bit,也就是可以表示85亿个不同的数

Map

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

可设定默认的value值

val mm = Map("zhangfei"->"zhangbashemao", "guanyu"->"qinglongyanyue")
  .withDefaultValue("bishou")

当不是集合中的key时输出vlaue

集合运算

  • map

    • flatmap:扁平化,将 元素抽出来
  • Filter

  • fold/reduce

    • fold 与reduce类似只是含有种子值

      • foldLeft种子值在左
      • foldright种子值在右
    • a|b|c|d|e

    • val listString = List("a","b","c","d")
      // :\代表foldRight,类似于reduceRight
      val x1 = (listString :\ "e")(_ +"|"+ _)
      
  • Flatten

    • 通过flatmap和flatten操作将集合中每个元素通过定制函数映射为新的扁平化结果集合。
  • Scan

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

    顾名思义,像拉链一样将两个集合链接起来。

Scala集合分类

  • 不变集合
    • Vector
    • List
    • Stream
  • 可变集合
    • ArrayBuffer
    • ListBuffer

即时计算vs延时计算

顺序计算Vs并行计算

Vector

  • Vector 是由元素的下标组成的前缀树

  • Vector 类目前可以被认为是这么一个通用的不可变数据结构。Vector是一个带索引的不可变序列 容器,如果你更倾向于使用一个链式不可变集合容器,那么你可以选择List。

  • 不能改变Vector,但是可以通过新生成Vector 的方式,为Vector 增加元素。

  • Vector作为一个集合类型,按地址随机存取元素效率是比较低的。但是Vector访问列表元素是高 效的,可以在常量时间完成。Vector在快速随机访问和快速随机存取方面是比较均衡的,Vectors现 在是immutable indexed sequences的默认实现。

  • 不适合频繁的头尾分解

List

  • 总在头上添加或者删除,性能表现不错
  • List 由两个类组成,一个是代表空列表的Nil ,另一个是Cons
  • List 继承自LinearSeq,适合头尾分解和头 部添加操作
  • 不适合中间元素修改,那么前半个List 都要 重新生成,不如Vector 通用

Stream

由cons 格子和空 stream 组成,类似于List,延迟计算元素的值

构造stream

val s = 1 #:: {
      println("HI")
      2
    } #:: {
      println("BAI")
      3
    } #:: {
      println("BAI")
      3
    } #:: Stream.empty
    
    println(s)//Stream(1,2,3,3,?)

视图与并行集合

并行vs串行vs并发vs分布式

假设有AB两个任务,则串行、并行、并发的区别如图1所示。

串行

A和B两个任务运行在一个CPU线程上,在A任务执行完之前不可以执行B。即,在整个程序的运行过程中,仅存在一个运行上下文,即一个调用栈一个堆。程序会按顺序执行每个指令。

并行

并行性指两个或两个以上事件或活动在同一时刻发生。在多道程序环境下,并行性使多个程序同一时刻可在不同CPU上同时执行。比如,A和B两个任务可以同时运行在不同的CPU线程上,效率较高,但受限于CPU线程数,如果任务数量超过了CPU线程数,那么每个线程上的任务仍然是顺序执行的。

并发

并发指多个线程在宏观(相对于较长的时间区间而言)上表现为同时执行,而实际上是轮流穿插着执行,并发的实质是一个物理CPU在若干道程序之间多路复用,其目的是提高有限物理资源的运行效率。 并发与并行串行并不是互斥的概念,如果是在一个CPU线程上启用并发,那么自然就还是串行的,而如果在多个线程上启用并发,那么程序的执行就可以是既并发又并行的。

而分布式和并行的区别如下:

分布式

分布式在并行处理的基础上,强调任务正在执行的物理设备,如处理器、内存等等硬件,在物理上是分开的。而并行计算是指在一台计算机上的计算,在物理上不分开。

  • Scala集合默认是严格和串行计算的,严格计算是指非延迟计算

  • 集合库通过两个标准机制来把默认执行方式转化为并行计算(par)或者延迟计算(view),分别是view和par,force方法是view方法的反操作,用来创建一个即时计算的新集合。Par方法的反向操作的seq。

在这里插入图片描述

aggregate

通常是par +aggreg结合使用。

  val rdd1 = List(1 to 100: _*)//扁平化

    val result: Int = rdd1.par.aggregate(0)(
      //acc=0
      (acc, number) => {//分片
        val res1 = acc + number
        println("par    " + acc + " + " + number + " = " + res1)
        res1
      },
      (par1, par2) => {//结合
        val res2 = par1 + par2
        println("com    " + par1 + " + " + par2 + " = " + res2)
        res2
      }
    )
    println(result)
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值