一、 集合简介

1)Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。

2)对于几乎所有的集合类,Scala都同时提供了 可变 不可变 的版本,分别位于以下两个包

不可变集合:scala.collection.immutable

可变集合:scala.collection.mutable

3)Scala不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java中的String对象

4)可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于java中StringBuilder对象

建议:在操作集合的时候,不可变用符号,可变用方法

1.1  不可变集合继承图

1)Set、Map是Java中也有的集合

2)Seq是Java没有的,我们发现List归属到Seq了,因此这里的List就和Java不是同一个概念了

3)我们前面的for循环有一个 1 to 3,就是IndexedSeq下的Range

4)String也是属于IndexedSeq

5)我们发现经典的数据结构比如Queue和Stack被归属到LinearSeq(线性序列)

6)大家注意Scala中的Map体系有一个SortedMap,说明Scala的Map可以支持排序

7)IndexedSeq和LinearSeq的区别:

(1) IndexedSeq 是通过索引来查找和定位,因此速度快,比如String就是一个索引集合,通过索引即可定位

(2) LinearSeq 是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找

1.2 可变集合继承图

2.1 不可变数组

定义:val arr1 = new Array[Int](10) (默认0)

(1)new是关键字

(2)[Int]是指定可以存放的数据类型,如果希望存放任意数据类型,则指定Any

(3)(10),表示数组的大小,确定后就不可以变化

2)案例实操

object Test03 {
  def main(args: Array[String]): Unit = {
    // 1. 创建数组
    // 1.1 直接new
    val arr1: Array[Int] = new Array[Int](5) //数组默认为0
    //1.2 用伴生对象创建
    //val arr2 = Array.apply(1,2,3,4,5)
    val arr2 = Array(1,2,3,4,5)
    //2.访问数组中元素
    println(arr2(4))  //5
    println(arr2.apply(4))  //5
    //3.数组赋值
    arr2(3) = 10
    println(arr2.mkString(",")) //1,2,3,10,5
    arr1(1) = 23
    println(arr1(1)) //23
    //4.遍历
    //4.1 遍历下标
    for( i <- 0 until arr1.length) print(arr1(i))
    for( i <- arr1.indices ) println(arr1(i))
    //4.2直接遍历数组
    for (elem <- arr1 ) println(elem)
    //4.2迭代器
    val iter = arr2.iterator
    while(iter.hasNext)
      println(iter.next())
    //4.3 调用foreach方法
    arr1.foreach((elem: Int) => println(elem))
    arr2.foreach(println)   //简写
    //5 用不可变数组实现添加数组
    //需要定义一个新的数组来接收返回值
    val newArr1 = arr1 .:+ (27)   //追加在后边
    val newArr2 = arr2  .+: (13)   //添加在最前边
    println(newArr1.mkString(","))
    println(newArr2.mkString(","))
    //添加多个元素
    val newArr3 = newArr1 :+ 35 :+ 13
    val newArr4 = 21 +: 19 +: newArr2 :+ 56
    println(newArr3.mkString(","))
    println(newArr4.mkString(","))

2.2 可变数组

1)定义变长数组

val arr01 = ArrayBuffer[Any](3, 2, 5)

(1)[Any]存放任意数据类型

(2)(3, 2, 5)初始化好的三个元素

(3)ArrayBuffer需要引入scala.collection.mutable.ArrayBuffer

2)案例实操

(1)ArrayBuffer是有序的集合

(2)增加元素使用的是append方法(),支持可变参数

object Test04 {
  def main(args: Array[String]): Unit = {
    //1. 创建可变数组
    val arr1: ArrayBuffer[Int] = new ArrayBuffer[Int]()
    val arr2 = ArrayBuffer(1, 2, 3)
    println(arr1) //ArrayBuffer()
    println(arr2) //ArrayBuffer(1, 2, 3)
    //2. 访问数组元素
    println(arr2(2)) //3
    arr2(2) = 15
    arr2.update(1, 27)
    println(arr2) //ArrayBuffer(1, 27, 15)
    // 3. 向数组添加元素
    val newArral1 = arr1 :+ 23
    val newArral2 = 12 +: arr2
    println(arr1) //ArrayBuffer()
    println(arr2) //ArrayBuffer(1, 27, 15)
    println(newArral1) //ArrayBuffer(23)
    println(newArral2) //ArrayBuffer(12, 1, 27, 15)
    println("-------------")
    //调用带英文名称的方法
    arr1.append(13)
    arr2.append(24, 78)
    arr1.prepend(36, 92)
    arr1.insert(1, 22, 18)
    println(arr1) //ArrayBuffer(36, 22, 18, 92, 13)
    println(arr2) //ArrayBuffer(1, 27, 15, 24, 78)
    arr1 += 31
    13 +=: arr1
    println(arr1) //ArrayBuffer(13, 36, 22, 18, 92, 13, 31)
    //4.删除数组元素
    val n = arr1.remove(2)
    println(n) //22
    println(arr1) //ArrayBuffer(13, 36, 18, 92, 13, 31)
    arr1 -= 13
    println(arr1) //ArrayBuffer(36, 18, 92, 13, 31)
    // 还可以用++=进行集合合并
    arr2 ++= ArrayBuffer(23, 45, 67)
    Array(12, 56) ++=: arr2
    println(arr2) //ArrayBuffer(12, 56, 1, 27, 15, 24, 78, 23, 45, 67)
    // 5. 可变数组和不可变数组的转换
    // 5.1 可变转不可变
    val arr: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)
    val newArr: Array[Int] = arr.toArray
    // 5.2 不可变转可变
    val buffer: mutable.Buffer[Int] = newArr.toBuffer
    println(buffer) //ArrayBuffer(1, 2, 3)
    //5.2 不可变转可变(利用空的转变成可变)
    val bArr = ArrayBuffer[Int]()
    bArr ++= newArr
    println(bArr)

2.3 不可变数组与可变数组的转换

arr1.toBuffer  //不可变数组转可变数组

arr2.toArray  //可变数组转不可变数组

(1)arr2.toArray返回结果才是一个不可变数组,arr2本身没有变化

(2)arr1.toBuffer返回结果才是一个可变数组,arr1本身没有变化

2)案例实操

    // 5. 可变数组和不可变数组的转换
    // 5.1 可变转不可变
    val arr: ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)
    val newArr: Array[Int] = arr.toArray
    // 5.2 不可变转可变
    val buffer: mutable.Buffer[Int] = newArr.toBuffer
    println(buffer) //ArrayBuffer(1, 2, 3)
    //5.2 不可变转可变(利用空的转变成可变)
    val bArr = ArrayBuffer[Int]()
    bArr ++= newArr
    println(bArr)

2.4 多维数组

1)多维数组定义

val arr = Array.ofDim[Double](3,4)

说明:二维数组中有三个一维数组,每个一维数组中有四个元素

2)案例实操

object Test05 {
  def main(args: Array[String]): Unit = {
    // 1. 创建二维数组
    val arr: Array[Array[Int]] = Array.ofDim[Int](2,3)
    // 2. 访问数组元素
    println(arr(0)(1))
    arr(0)(1) = 13
    println(arr(0)(1))
    // 3. 遍历数组
//    for ( i <- 0 until arr.length; j <- 0 until arr(i).length)
      for (i <- arr.indices; j <- arr(i).indices){
        print(arr(i)(j) + "\t")
        if (j == arr(i).length - 1) println()
    arr.foreach(line => line.foreach(println))
 //   arr.foreach(_.foreach(println))

三、 Seq集合(List)

3.1 不可变List

(1)List默认为不可变集合

(2)创建一个List(数据有顺序,可重复)
(3)遍历List

(4)List增加数据

(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化
(6)取指定数据
(7)空集合Nil

object Test06 {
  def main(args: Array[String]): Unit = {
    // 1. 创建List
    val list1: List[Int] = List(1, 2, 3, 4)
    println(list1) //List(1, 2, 3, 4)
    // 2. 访问List元素,遍历
    println(list1(3)) //4
    for (elem <- list1) println(elem) // 1  2  3  4
    list1.foreach(println)     // 1  2  3  4
    // 3. 向列表里添加数据
    val list2 = 10 +: list1
    val list3 = list2 :+ 24
    println(list1) //List(1, 2, 3, 4)
    println(list2) //List(10, 1, 2, 3, 4)
    println(list3) //List(10, 1, 2, 3, 4, 24)
    // 4. 特殊的List,以及用它来构建列表
    val list4 = list1.::(52)
    val list5 = Nil.::(12)
    println(list4) //List(52, 1, 2, 3, 4)
    println(list5) //List(12)
    val list6 = 13 :: list5
    val list7 = 15 :: 24 :: 67 :: Nil
    println(list6) //List(13, 12)
    println(list7) //List(15, 24, 67)
    // 5. 扁平化
    val list8: List[Any] = list6 :: list7
    println(list8)    //List(List(13, 12), 15, 24, 67)
    val list9: List[Int] = list6 ::: list7
    println(list9)    //List(13, 12, 15, 24, 67)
    val list10 = list6 ++ list7
    println(list10)   //List(13, 12, 15, 24, 67)

3.2 可变ListBuffer

(1)创建一个可变集合ListBuffer

(2)向集合中添加数据

(3)打印集合数据

2)案例实操

object Test07 {
  def main(args: Array[String]): Unit = {
    // 1. 创建可变List
    val list1: ListBuffer[Int] = new ListBuffer[Int]()
    val list2 = ListBuffer(1,2,3)
    // 2. 添加数据
    list1.append(12)    //ListBuffer(12)
    list2.append(23,57)  //ListBuffer(1, 2, 3, 23, 57)
    list1.append(13,22)  //ListBuffer(12, 13, 22)
    list1 += 65 += 39   //ListBuffer(12, 13, 22, 65, 39)
    11 +=: list2    //ListBuffer(11, 1, 2, 3, 23, 57)
    println(list1)
    println(list2)
    // 3. 合并List
    val list3 = list1 ++ list2
    list1 ++= list2
    list1 ++=: list2
    println(list1)  //ListBuffer(12, 13, 22, 65, 39, 11, 1, 2, 3, 23, 57)
    println(list2) //ListBuffer(12, 13, 22, 65, 39, 11, 1, 2, 3, 23, 57, 11, 1, 2, 3, 23, 57)
    println(list3)  //ListBuffer(12, 13, 22, 65, 39, 11, 1, 2, 3, 23, 57)
    // 4. 修改元素
    list3(2) = 33
    list3.update(4,55)
    println(list3)  //ListBuffer(12, 13, 33, 65, 55, 11, 1, 2, 3, 23, 57)
    // 5. 删除元素
    list3.remove(6,2)  //ListBuffer(12, 13, 33, 65, 55, 11, 3, 23, 57)
    val list4 = list3 - 33 //ListBuffer(12, 13, 65, 55, 11, 3, 23, 57)
    list3 -= 23  //ListBuffer(12, 13, 33, 65, 55, 11, 3, 57)
    println(list4)
    println(list3)

四、Set集合

默认情况下,Scala使用的是不可变集合,如果你想使用可变集合,需要引用 scala.collection.mutable.Set 包

4.1 可变Set与不可变Set

(1)Set默认是不可变集合,数据无序,创建可变集合mutable.Set(向集合中添加元素,返回一个新的Set)

(2)数据不可重复

(3)遍历集合

2)案例实操

object Test09 {
  def main(args: Array[String]): Unit = {
    // 1. 不可变Set
    // 1.1 创建
    val set1: Set[Int] = Set(1, 4, 2, 5, 5, 27, 67)
    println(set1)  //Set(5, 1, 2, 27, 67, 4)
    // 1.2 添加元素
    val set2 = set1 + 21
    println(set1)   //Set(5, 1, 2, 27, 67, 4)
    println(set2)   //Set(5, 1, 21, 2, 27, 67, 4)
    //1.3 合并set
    val set3 = Set(1,27,43,79)
    val set4 = set2 ++ set3
    println(set4)   //Set(5, 1, 21, 2, 27, 67, 43, 4, 79)
    // 1.4 删除元素
    val set5 = set4 - 21
    println(set5)   //Set(5, 1, 2, 27, 67, 43, 4, 79)
    // 2. 可变Set
    // 2.1 创建
    val set6: mutable.Set[Int] = mutable.Set(1,2,3,4)
    // 2.2 添加元素
    set6.add(35)
    println(set6.add(1))  //false
    // 2.3 删除元素
    println(set6.remove(2))
    println(set6)   //Set(1, 35, 3, 4)
    set6 -=2
    val set7 = set6 - 2
    // 2.4 合并集合
    val set8 = set6 ++ set1
    println(set6)
    println(set8)
    set6 ++= set1
    println(set6)

五、 Map集合

Scala中的Map和Java类似,也是一个散列表,它存储的内容也是键值对(key-value映射

5.1 可变Map与不可变Map

2)案例实操

object Test08 {
  def main(args: Array[String]): Unit = {
    // 1. 不可变Map
    // 1.1 创建
    val map1: Map[String, Int] = Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4)
    println(map1)
    // 1.2 遍历map元素
    map1.foreach(println) //(a,1)(b,2)(c,3)(d,4)
    map1.keys.foreach(println) //abcd
    map1.values.foreach(println) //1234
    println("*************")
    // 1.3 单独访问元素
    println(map1.get("c").getOrElse(0)) //3
    println(map1.getOrElse("c", 0)) // 3
    // 2. 可变Map
    // 2.1 创建
    val map2: mutable.Map[String, Int] = mutable.Map("a" -> 1, "b" -> 2, "c" -> 3, "d" -> 4)
    // 2.2 添加元素
    map2.put("d", 67)
    map2.put("e", 13)
    map2 += ("f" -> 25)
    println(map2)
    // 2.3 修改和删除
    map2.update("d", 31)
    println(map2("d"))
    map2("b") = 69
    map2.remove("c")
    map2 -= "c"
    map2 .-= ("c","d")
    println(map2)
    // 2.4 合并两个Map
    val map3 = map1 ++ map2
    map2 ++= map1
    println(map1)
    println(map2)
    println(map3)

六、 元组

元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。

注意:元组中最大只能有22个元素。

2)案例实操

(1)声明元组的方式:(元素1,元素2,元素3)

(2)访问元组

(3)Map中的键值对其实就是元组,只不过元组的元素个数为2,称之为对偶

object Test08_Tuple {
  def main(args: Array[String]): Unit = {
    // 1. 创建一个元组
    val tuple1: (Int, String, Double, Char) = (100, "hello", 12.3, 'c')
    println(tuple1)
    // 2. 访问元组数据
    //(2.1)通过元素的顺序进行访问,调用方式:_顺序号
    println(tuple1._3)
//    tuple1._2 = ""      // error, 不能重新赋值
    //(2.2)通过索引访问数据
    println(tuple1.productElement(0))
    // 3. 遍历数据
//    for( elem <- tuple1 ) println(elem)    // 元组中没有foreach方法
//    tuple1.foreach()
    //通过迭代器访问数据
    for( elem <- tuple1.productIterator) println(elem)
    // 4. 元组和map的键值对 //Map中的键值对其实就是元组,只不过元组的元素个数为2,称之为对偶       
//    val map1 = Map("a"->1, "b"->2, "c"->3)
//    println(map1)
    val map1 = Map(("a",1), ("b",2), ("c",3))
    map.foreach(tuple=>{println(tuple._1 + "=" + tuple._2)})
    // 5. 嵌套元组
    val tuple2: (Int, Double, String, List[Int], (Char, Int)) = (12, 0.9, "hi", List(1, 2), ('c', 15))
    println(tuple2._5._2)
    val tuple3 = (1,1,2,2)
    val tuple4 = (("a", 1), ("a", 2))
    println(tuple4)

七、 集合常用函数

7.1 基本属性和常用操作

(1)获取集合长度

(2)获取集合大小

(3)循环遍历

(4)迭代器

(5)生成字符串

(6)是否包含

2)案例实操

object TestList {
  def main(args: Array[String]): Unit = {
    val list: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
    //(1)获取集合长度
    println(list.length)
    //(2)获取集合大小,等同于length
    println(list.size)
    //(3)循环遍历
    list.foreach(println)
    //(4)迭代器
    for (elem <- list.itera	tor) {
      println(elem)
    //(5)生成字符串
    println(list.mkString(","))
    //(6)是否包含
    println(list.contains(3))

7.2 衍生集合

(1)获取集合的头

(2)获取集合的尾(不是头的就是尾)

(3)集合最后一个数据

(4)集合初始数据(不包含最后一个)

(5)反转

(6)取前(后)n个元素

(7)去掉前(后)n个元素

(8)并集

(9)交集

(10)差集

(11)拉链

(12)滑窗

2)案例实操

object Test05 {
  def main(args: Array[String]): Unit = {
    val list1 = List(1,2,3,4,5,6,6,7)
    val list2 = List(5,4,6,7,8,9,10,11,12)
    //    (1)获取集合的头
    println(list1.head)   //1
    //    (2)获取集合的尾(不是头的就是尾)
    println(list1.tail)   //List(2, 3, 4, 5, 6, 6, 7)
    //    (3)集合最后一个数据
    println(list1.last)   //7
    //    (4)集合初始数据(不包含最后一个)
    println(list2.init)  //List(5, 4, 6, 7, 8, 9, 10, 11)
    //    (5)反转
    println(list2.reverse)  //List(12, 11, 10, 9, 8, 7, 6, 4, 5)
    //    (6)取前(后)n个元素
    println(list1.take(3))   //List(1, 2, 3)
    println(list2.takeRight(3))  //List(10, 11, 12)
    //    (7)去掉前(后)n个元素
    println(list1.drop(3))   //List(4, 5, 6, 6, 7)
    //    (8)并集
    val union = list1.union(list2)
    println(union) //List(1, 2, 3, 4, 5, 6, 6, 7, 5, 4, 6, 7, 8, 9, 10, 11, 12)
    println(list2.union(list1)) //List(5, 4, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 6, 7)
    //set的并集去重的,set本身数据无序,不可重复
    val set1 = Set(1,2,3,4,5,6,7)
    val set2 = Set(4,5,6,7,8,9,10,11,12)
    val unionSet = set1.union(set2)
    println(unionSet)  //Set(5, 10, 1, 6, 9, 2, 12, 7, 3, 11, 8, 4)
    println(set2.union(set1))   //Set(5, 10, 1, 6, 9, 2, 12, 7, 3, 11, 8, 4)
    //    (9)交集
    val intersectionSet: Set[Int] = set1.intersect(set2)
    println(intersectionSet)   //Set(5, 6, 7, 4)
    println(list1.intersect(list2))  //List(4, 5, 6, 7)
    println(list2.intersect(list1))   //List(5, 4, 6, 7)
    //    (10)差集
    println(list1.diff(list2))  //List(1, 2, 3, 6)
    println(list2.diff(list1))  //List(8, 9, 10, 11, 12)
    //    (11)拉链
    //注:如果两个集合的元素个数不相等,那么会将同等数量的数据进行拉链,多余的数据省略不用
    println(list1.zip(list2))
    //    (12)滑窗
    // 12.1 单参数,步长为1
    for(elem <- list2.sliding(5)) println(elem)  //List(5, 4, 6, 7, 8) List(4, 6, 7, 8, 9) List(6, 7, 8, 9, 10) List(7, 8, 9, 10, 11) List(8, 9, 10, 11, 12)
    // 12.2 两参数,size和步长
    for(elem <- list2.sliding(5,3)) println(elem)  //List(5, 4, 6, 7, 8) List(7, 8, 9, 10, 11) List(10, 11, 12)
    // 12.3 整体滑动
    for( elem <- list2.sliding(3,3)) println(elem)  //List(5, 4, 6) List(7, 8, 9) List(10, 11, 12)

7.3 集合计算初级函数

       (1)求和

       (2)求乘积

       (3)最大值

       (4)最小值

       (5)排序

object TestList {
  def main(args: Array[String]): Unit = {
    val list: List[Int] = List(1, 5, -3, 4, 2, -7, 6)
    //(1)求和
    println(list.sum)
    //(2)求乘积
    println(list.product)
    //(3)最大值
    println(list.max)
    //(4)最小值
    println(list.min)
    //(5)排序
    // (5.1)按照元素大小排序
    println(list.sortBy(x => x))
    // (5.2)按照元素的绝对值大小排序
    println(list.sortBy(x => x.abs))
    // (5.3)按元素大小升序排序
   println(list.sortWith((x, y) => x < y))
   // (5.4)按元素大小降序排序
    println(list.sortWith((x, y) => x > y))

(1)sorted

对一个集合进行自然排序,通过传递隐式的Ordering

(2)sortBy

对一个属性或多个属性进行排序,通过它的类型。

(3)sortWith

基于函数的排序,通过一个comparator函数,实现自定义排序的逻辑。

7.4 集合计算高级函数

(1)过滤

       遍历一个集合并从中获取满足指定条件的元素组成一个新的集合

(2)转化/映射(map

       将集合中的每一个元素映射到某一个函数

(3)扁平化

(4)扁平化+映射 注:flatMap相当于先进行map操作,在进行flatten操作

        集合中的每个元素的子元素映射到某个函数并返回新集合

(5)分组(group)

       按照指定的规则对集合的元素进行分组

(6)简化(归约)      

(7)折叠

object Test06 {
  def main(args: Array[String]): Unit = {
    val list = List(1,2,3,4,5,6,7,8,9)
    // 1. 过滤
    // 筛选所有的偶数
    val newList: List[Int] = for ( i <- list if i % 2 ==0) yield i
    println(newList)  //List(2, 4, 6, 8)
    val evenList = list.filter(_ % 2 == 0)
    println(evenList) //List(2, 4, 6, 8)
    //2.转化/映射==>map
    println(list.map(_ * 2 + "data"))  //List(2data, 4data, 6data, 8data, 10data, 12data, 14data, 16data, 18data)
    println(list.map(x => x + 1))  //List(2, 3, 4, 5, 6, 7, 8, 9, 10)
    // 3. 扁平化
    val nestedList: List[List[Int]] = List(List(1,2,4),List(3,7,9),List(23,46,67))
    val flatList: List[Int] = nestedList.flatten
    println(flatList)  //List(1, 2, 4, 3, 7, 9, 23, 46, 67)
    //4. 扁平映射 ==> 注:flatMap相当于先进行map操作,在进行flatten操作
    val stringList: List[String] = List("hello scala", "hello world", "hello atguigu")
    println(stringList.map(str => str.split(" ")).flatten)   //List(hello, scala, hello, world, hello, atguigu)
    println(stringList.flatMap(_.split(" ")))  //List(hello, scala, hello, world, hello, atguigu)
    // 5. 分组
    // 按照奇偶性分组
    val groupedMap: Map[String,List[Int]] = list.groupBy(data => if(data % 2 == 0) "偶数" else "奇数")
    println(groupedMap)
    // 按照字符串首字母分组
    val strings: List[String] = List("china","canada","usa","japan","uk")
    println(strings.groupBy(_.charAt(0)))

3Reduce方法

Reduce简化(归约) :通过指定的逻辑将集合中的数据进行聚合,从而减少数据,最终获取结果。

object Test07 {
  def main(args: Array[String]): Unit = {
    val list = List(1,2,3,4)
    // 1. reduce
    val res1 = list.reduce((a:Int,b:Int) => a + b)
    val res2 = list.reduce(_ + _)
    val res3 = list.reduceLeft(_+_)
    val res4 = list.reduceRight(_+_)
    println(res1)   //10
    println(res2)   //10
    println(res3)   //10
    println(res4)   //10
     从源码的角度,reduce底层调用的其实就是reduceLeft
    // 关于左右规约,减法规约
    println(list.reduceLeft(_ - _))  //-8
    println(list.reduceRight(_ - _)) //-2
    val list2 = List(3,4,5,8,10)
    println(list2.reduceLeft(_ - _))  // -24  3-4-5-8-10
    println(list2.reduceRight(_ - _))  // 6  3-(4-(5-(8-10)))
    //2.fold
    val res5 = list.fold(10)(_ - _) // 0    10-1-2-3-4
    println(res5)
    println(list2.foldRight(11)(_ - _))   // -5  3-(4-(5-(8-(10-11)))

4Fold方法

Fold折叠:简化的一种特殊情况。

    (1)案例实操:fold基本使用

object TestFold {
    def main(args: Array[String]): Unit = {
        val list = List(1,2,3,4)
        // fold方法使用了函数柯里化,存在两个参数列表
        // 第一个参数列表为 : 零值(初始值)
        // 第二个参数列表为: 简化规则
        // fold底层其实为foldLeft
        val i = list.foldLeft(1)((x,y)=>x-y)
        val i1 = list.foldRight(10)((x,y)=>x-y)
        println(i)
        println(i1)

 (2)案例实操:两个集合合并

object TestFold {
    def main(args: Array[String]): Unit = {
        // 两个Map的数据合并
        val map1 = mutable.Map("a"->1, "b"->2, "c"->3)
        val map2 = mutable.Map("a"->4, "b"->5, "d"->6)
        val map3: mutable.Map[String, Int] = map2.foldLeft(map1) {
            (map, kv) => {
                val k = kv._1
                val v = kv._2
                map(k) = map.getOrElse(k, 0) + v
        println(map3)

7.5 普通WordCount案例

       单词计数:将集合中出现的相同的单词,进行计数,取计数排名前三的结果

2)需求分析

3)案例实操

object TestWordCount {
    def main(args: Array[String]): Unit = {
        // 单词计数:将集合中出现的相同的单词,进行计数,取计数排名前三的结果
        val stringList = List("Hello Scala Hbase kafka", "Hello Scala Hbase", "Hello Scala", "Hello")
        // 1) 将每一个字符串转换成一个一个单词
        val wordList: List[String] = stringList.flatMap(str=>str.split(" "))
        //println(wordList)
        // 2) 将相同的单词放置在一起
        val wordToWordsMap: Map[String, List[String]] = wordList.groupBy(word=>word)
        //println(wordToWordsMap)
        // 3) 对相同的单词进行计数
        // (word, list) => (word, count)
        val wordToCountMap: Map[String, Int] = wordToWordsMap.map(tuple=>(tuple._1, tuple._2.size))
        // 4) 对计数完成后的结果进行排序(降序)
        val sortList: List[(String, Int)] = wordToCountMap.toList.sortWith {
            (left, right) => {
                left._2 > right._2
        // 5) 对排序后的结果取前3名
        val resultList: List[(String, Int)] = sortList.take(3)
        println(resultList)
object Test13_WordCount {
  def main(args: Array[String]): Unit = {
    // 1. 简单版本
    val stringList = List(
      "hello",
      "hello world",
      "hello scala",
      "hello spark in scala",
      "hello flink in scala"
    // 1.1 按空格切分字符串,得到打散的word
    val wordList0 = stringList.map( str => str.split(" ") )
//    println(wordList0.flatten)
    val wordList = stringList.flatMap( _.split(" ") )
    println(wordList)
    // 1.2 按照单词自身作为key分组
    val groupMap: Map[String, List[String]] = wordList.groupBy( word => word )
    println(groupMap)
    // 1.3 对分组的word列表进行length统计,得到(word,count)
    val countMap: Map[String, Int] = groupMap.map( kv => (kv._1, kv._2.length) )
    println(countMap)
    // 1.4 排序取top3
    val sortList: List[(String, Int)] = countMap
      .toList    // 转换成list
//        .sortWith( (data1, data2) => data1._2 > data2._2 )
      .sortWith( _._2 > _._2 )    // 按照count值从大到小排序
      .take(3)    // 选取前3
    println(sortList)

7.6 复杂WordCount案例

1)方式一

object TestWordCount {
    def main(args: Array[String]): Unit = {
        // 第一种方式(不通用)
        val tupleList = List(("Hello Scala Spark World ", 4), ("Hello Scala Spark", 3), ("Hello Scala", 2), ("Hello", 1))
        val stringList: List[String] = tupleList.map(t=>(t._1 + " ") * t._2)
        //val words: List[String] = stringList.flatMap(s=>s.split(" "))
        val words: List[String] = stringList.flatMap(_.split(" "))
        //在map中,如果传进来什么就返回什么,不要用_省略
        val groupMap: Map[String, List[String]] = words.groupBy(word=>word)
        //val groupMap: Map[String, List[String]] = words.groupBy(_)
        // (word, list) => (word, count)
        val wordToCount: Map[String, Int] = groupMap.map(t=>(t._1, t._2.size))
        val wordCountList: List[(String, Int)] = wordToCount.toList.sortWith {
            (left, right) => {
                left._2 > right._2
        }.take(3)
        //tupleList.map(t=>(t._1 + " ") * t._2).flatMap(_.split(" ")).groupBy(word=>word).map(t=>(t._1, t._2.size))
        println(wordCountList)

2)方式二

object TestWordCount {
    def main(args: Array[String]): Unit = {
        val tuples = List(("Hello Scala Spark World", 4), ("Hello Scala Spark", 3), ("Hello Scala", 2), ("Hello", 1))
        // (Hello,4),(Scala,4),(Spark,4),(World,4)
        // (Hello,3),(Scala,3),(Spark,3)
        // (Hello,2),(Scala,2)
        // (Hello,1)
        val wordToCountList: List[(String, Int)] = tuples.flatMap {
            t => {
                val strings: Array[String] = t._1.split(" ")
                strings.map(word => (word, t._2))
        // Hello, List((Hello,4), (Hello,3), (Hello,2), (Hello,1))
        // Scala, List((Scala,4), (Scala,3), (Scala,2)
        // Spark, List((Spark,4), (Spark,3)
        // Word, List((Word,4))
        val wordToTupleMap: Map[String, List[(String, Int)]] = wordToCountList.groupBy(t=>t._1)
        val stringToInts: Map[String, List[Int]] = wordToTupleMap.mapValues {
            datas => datas.map(t => t._2)
        stringToInts
        val wordToCountMap: Map[String, List[Int]] = wordToTupleMap.map {
            t => {
                (t._1, t._2.map(t1 => t1._2))
        val wordToTotalCountMap: Map[String, Int] = wordToCountMap.map(t=>(t._1, t._2.sum))
        println(wordToTotalCountMap)

 2)方式三

object Test10 {
  def main(args: Array[String]): Unit = {
    val tupleList: List[(String, Int)] = List(
      ("hello world", 1),
      ("hello scala", 2),
      ("hello spark in scala", 3),
      ("hello flink in scala", 4)
    val wordCountMap1 = tupleList.flatMap(kv =>{
      val strList = kv._1.split(" ")
      strList.map(word => (word,kv._2))
    })                                    //List((hello,1), (world,1), (hello,2), (scala,2), (hello,3), (spark,3), (in,3), (scala,3), (hello,4), (flink,4), (in,4), (scala,4))
        .groupBy(_ ._1 )                 //Map(in -> List((in,3), (in,4)), world -> List((world,1)), flink -> List((flink,4)), spark -> List((spark,3)), scala -> List((scala,2), (scala,3), (scala,4)), hello -> List((hello,1), (hello,2), (hello,3), (hello,4)))
        .toList                         // List((in,List((in,3), (in,4))), (world,List((world,1))), (flink,List((flink,4))), (spark,List((spark,3))), (scala,List((scala,2), (scala,3), (scala,4))), (hello,List((hello,1), (hello,2), (hello,3), (hello,4))))
        .map(kv => {
          (kv._1,kv._2.map(_._2))
        })                                //List((in,List(3, 4)), (world,List(1)), (flink,List(4)), (spark,List(3)), (scala,List(2, 3, 4)), (hello,List(1, 2, 3, 4)))
        .map(kv => (kv._1,kv._2.sum))    //List((in,7), (world,1), (flink,4), (spark,3), (scala,9), (hello,10))
        .sortBy(_._2).reverse            //List((hello,10), (scala,9), (in,7), (flink,4), (spark,3), (world,1))
        .take(3)                        //List((hello,10), (scala,9), (in,7))
    println(wordCountMap1)

八、 队列

Scala也提供了队列(Queue)的数据结构,队列的特点就是先进先出。进队和出队的方法分别为enqueue和dequeue。

2)案例实操

object TestQueue {
    def main(args: Array[String]): Unit = {
        val que = new mutable.Queue[String]()
        que.enqueue("a", "b", "c")
        println(que.dequeue())
        println(que.dequeue())
        println(que.dequeue())

九 、并行集合

Scala为了充分使用多核CPU,提供了并行集合(有别于前面的串行集合),用于多核环境的并行计算。

2)案例实操

object TestPar {
    def main(args: Array[String]): Unit = {
        val result1 = (0 to 100).map{case _ => Thread.currentThread.getName}
        val result2 = (0 to 100).par.map{case _ => Thread.currentThread.getName}
        println(result1)
        println(result2)
                    一、集合的简介1)Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。2)对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本,分别位于以下两个包不可变集合:scala.collection.immutable可变集合:scala.collection.mutable3)Scala不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java中的String对象4)可变集合,就是这个集
				
Scala集合分为三大类序列Seq,集Set 以及映射Map。所有的集合都扩展自 Iterable 特质在 Scala集合有可变(“scala.collection.mutable” 包下存放)和不可变(“scala.collection.immutable” 包下存放)两种类型。 var greeting:String = "Hello world!"; 每当遇到一个字符串在代码中,编译器创建String对象及其值,在这个示例中使用:“Hello world!”,但如果你喜欢,可以给字符串,因为这里我已经在声明中交替显示。 (1)Scala集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。 (2)对于几乎所有的集合类,Scala都同时提供了可变和不可变的版本,分别位于以下两个包。 不可变集合scala.collection.immutable 可变集合scala.collection.mutable (3)不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java中的String对象 (4)可变集合,就是这个.
object CollectionReview { def main(args: Array[String]): Unit = { val ints = List(1,3,2,5,2,4,4) //contains println(ints.contains(4))//true //distinct println(ints.distinct)//13254 //isEmpty println(ints.isEmpt
从较高的层次来看 Scala 集合,主要有以下三个类别可供选择: Sequences是元素的顺序集合,可以是索引的(如数组)或线性的(如链表); Maps包含键/值对的集合,类似于Java的Map、Python的dict; Sets是唯一元素的无序集合; 所有这些都是基本类型,并且具有用于特定目的的子类型,例如并发、缓存和流式处理。除了这三个主要类别之外,还有其他有用的集合类型,包括ranges, stacks, queues。
Scala集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质,意味着 集合的基本特点是⽀持迭代遍历的。 scala集合两个主要的包: # 不可变集合 scala.collection.immutable (Scala默认采用. 1)Scala集合有三大类:序列 Seq、集 Set、映射 Map,所有的集合都扩展自 Iterable 2)对于几乎所有的集合类,Scala 都同时提供了可变和不可变的版本,分别位于以下两 不可变集合scala.collection.immutable 可变集合scala.collection.mutable 3)Scala 不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而 不会对原对象进行修改。类似于 java 中的 Str Scala 集合分为可变的和不可变的集合。 默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用scala.collection.mutable.Set包。 默认引用 scala.collection.immutable.Set,不可变集合实例如下: 1.定义: var set1 =Set(1,"一",2,"er") set1.foreach(x => println(x)) 1.集合简介 1)Scala集合有三大类:序列 Seq、集 Set、映射 Map,所有的集合都扩展自 Iterable特质。 2)对于几乎所有的集合类,Scala 都同时提供了可变和不可变的版本,分别位于以下两个包 不可变集合scala.collection.immutable 可变集合scala.collection.mutable 3)Scala 不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。 类似于 java 中的 String 对象 Scala集合有三大类: 序列seq, 集Set, 映射Map, 所有的集合都扩展自 Iterable 特质; 对于几乎所有的集合类, Scala都同时提供了可变和不可变的版本. 分别位于以下两个包: scala.collection.immutable, scala.collection.mutable Q:什么是可变,不可变集合? a. Scala 不可变集合, 就是指该集合对象不可修