学习链接:https://www.bilibili.com/video/BV1Xh411S7bP?p=91&spm_id_from=pageDriver


1 集合简介

  1. Scala的集合:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质
  2. 对于几乎所有的集合类,Scala都提供了可变和不可变的版本,分别位于一下两个包:
    1. 不可变集合:scala.collection.immutable,指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改,类似于java中的String对象。
    2. 可变集合:scala.collection.mutable,这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于java中StringBuilder对象

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

1.1 不可变集合继承图

284c83ed1bc3475292815cb8385a0873.png

1.2 可变集合继承图

827f92fc773149969cd20ebb8fd47147.png

2 数组

2.1 不可变数组

2.1.1 定义数组

  • 方式一:val arr1 = new ArrayInt
    • new是关键字
    • [Int]是指定存放的数据类型,如果希望存放任意数据类型,指定Any
    • (10),表示数组的大小,确定后就不可以变化
  • 方式二:val arr1 = Array(1, 2)
    • 在定义数组时,直接赋初始值
    • 使用apply方法创建数组对象
      1. // 1. 创建数组
      2. val arr: Array[Int] = new Array[Int](5)
      3. // 另一种创建方式
      4. val arr2 = Array(12, 37, 42, 58, 97)

      2.1.2 访问元素

      ```scala // 2. 访问元素 println(arr(0)) // 0 println(arr(1)) // 0 // println(arr(5)) error 数组越界

arr(0) = 21 arr(1) = 90 println(arr(0)) // 21 println(arr(1)) // 90

<a name="jpQlK"></a>
### 2.1.3 遍历数组
```scala
// 3. 数组遍历
// 1) 普通for循环 0 <= i <arr.length
for (i <- 0 until arr.length) {
  println(arr(i))
}

// def indices: Range = 0 until length
for (i <- arr.indices) {
  println(arr(i))
}

// 2) 遍历所有元素,增强for循环
for (elem <- arr2) {
  println(elem)
}

// 3) 迭代器
val iter = arr2.iterator
while (iter.hasNext) {
  println(iter.next())
}

// 4) foreach方法
arr2.foreach((elem: Int) => println(elem))

arr.foreach(println)

println(arr2.mkString("--")) // 12--37--42--58--97

2.1.4 添加元素

// 4. 添加元素
val newArray = arr2.:+(73) // 把新添加的元素添加到末尾
println(newArray.mkString("--")) // 12--37--42--58--97--73

val newArray2 = newArray.+:(30) // 把新添加的元素添加到开头
println(newArray2.mkString("--")) // 30--12--37--42--58--97--73

val newArray3 = newArray2 :+ 15 // 15添加到末尾
val newArray4 = 29 +: newArray3 // 29添加到开头
val newArray5 = 19 +: 29 +: newArray3 :+ 26 :+73 // 连续添加
println(newArray5.mkString(",")) // 19,29,30,12,37,42,58,97,73,15,26,73

2.2 可变数组

ArrayBuffer 需要引入 scala.collection.mutable.ArrayBuffer

def main(args: Array[String]): Unit = {
  // 1. 创建可变数组
  val arr1: ArrayBuffer[Int] = new ArrayBuffer[Int]()

  val arr2 = ArrayBuffer(23, 24, 25)

  println(arr1.mkString(",")) // 什么都不输出
  println(arr2) // ArrayBuffer(23, 24, 25)

  // 2. 访问数组中的元素
  //    println(arr1(0)) error 数组越界
  println(arr2(1)) // 24

  arr2(1) = 39
  println(arr2(1))

  // 3. 添加元素
  val newArr = arr1 :+ 15 // 直接添加没有用,主要针对不可变数组,除非把它赋给新的数组
  println(arr1) // ArrayBuffer()
  println(newArr) // ArrayBuffer(15)
  println(arr1 == newArr) // false

  arr1 += 19 // 也可以把它赋给新的数组,最好别
  println(arr1) // ArrayBuffer(19)

  val arr = arr1 += 30
  println(arr1) // ArrayBuffer(19, 30)
  println(arr == arr1) // true

  // 从前面追加
  77 +=: arr1
  println(arr1) // ArrayBuffer(77, 19, 30)

  arr1.append(26) // 末尾添加
  arr1.prepend(21, 25) // 开头添加
  arr1.insert(1, 13, 59) // 在索引1处添加13和59
  println(arr1) // ArrayBuffer(21, 13, 59, 25, 77, 19, 30, 26)

  arr1.insertAll(2, newArr) // 在索引2处添加newArr中的所有
  arr1.appendAll(newArr)
  arr1.prependAll(newArr)
  arr1.append(15, 16, 15)

  // 4. 删除元素
  arr1.remove(3)
  arr1.remove(0, 4)

  arr1 -= 15 // 从arr1中删掉15,如果数组里没有15,相当于什么都不做,有重复删除第一个
}

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

def main(args: Array[String]): Unit = {
  // 5. 可变数组转换为不可变数组
  val arr = ArrayBuffer(23, 56, 98)
  val newArr: Array[Int] = arr.toArray

  // 6. 不可变数组转换为可变数组
  val buffer: mutable.Buffer[Int] = newArr.toBuffer
  println(buffer) // ArrayBuffer( 23, 56, 98)
  println(newArr) // [I@96532d6
}

2.4 多维数组

def main(args: Array[String]): Unit = {
  // 1. 创建二维数组
  val array: Array[Array[Int]] = Array.ofDim[Int](2, 3) // 2行3列的二维数组

  // 2. 访问元素
  array(0)(2) = 19
  array(1)(0) = 25

  for (i <- 0 until array.length; j <- 0 until array(i).length) {
    println(array(i)(j))
  }

  for (i <- array.indices; j <- array(i).indices) {
    print(array(i)(j) + "\t")
    if (j == array(i).length - 1) {
      println()
    }
  }

  array.foreach(line => line.foreach(println))

  array.foreach(_.foreach(println))
}

3 列表

3.1 不可变List

def main(args: Array[String]): Unit = {
  // 1. 创建一个List
  val list1 = List(25, 23, 56) // 用apply方法
  println(list1) // List(25, 23, 56)

  // 2. 访问和遍历元素
  println(list1(1)) // 23
  //    list1(1) = 12 error 不能更改值

  list1.foreach(println)

  // 3. 添加元素
  val list2 = 10 +: list1 // 在前面添加
  val list3 = list1 :+ 20 // 在后面添加

  println(list1) // List(25, 23, 56)
  println(list2) // List(10, 25, 23, 56)
  println(list3) // List(25, 23, 56, 20)

  val list4 = list2.::(51) // 把51加在前面
  println(list4) // List(51, 10, 25, 23, 56)

  // 空集合Nil
  // ::的运算规则从右向左
  val list5 = Nil.::(13)
  val list6 = 32 :: Nil
  val list7 = 17 :: 28 :: 59 :: 16 :: Nil // List(17, 28, 59, 16)

  // 合并列表
  val list8 = list6 :: list7
  println(list8) // List(List(32), 17, 28, 59, 16)

  val list9 = list6 ::: list7 // 扁平化
  println(list9) // List(32, 17, 28, 59, 16)

  val list10 = list6 ++ list7
  println(list10) // List(32, 17, 28, 59, 16)
}

3.2 可变ListBuffer

def main(args: Array[String]): Unit = {
  // 1. 创建可变列表
  val list1 = new ListBuffer[Int]()
  val list2 = ListBuffer(12, 52, 56)

  println(list1) // ListBuffer()
  println(list2) // ListBuffer(12, 52, 56)

  // 2. 添加元素
  list1.append(15, 62)
  list2.prepend(20)

  list1.insert(1, 19, 22)

  println(list1) // ListBuffer(15, 19, 22, 62)
  println(list2) // ListBuffer(20, 12, 52, 56)

  list1 += 25 += 11
  31 +=: 96 +=: list1
  println(list1) // ListBuffer(31, 96, 15, 19, 22, 62, 25, 11)

  31 +=: 96 +=: list2 += 25 += 11
  println(list2)

  // 3. 合并list
  val list3 = list1 ++ list2 // list1和list2不更改

  list1 ++= list2 // 在list1后面追加list2
  println(list1) // ListBuffer(31, 96, 15, 19, 22, 62, 25, 11, 31, 96, 20, 12, 52, 56, 25, 11)
  println(list2) // ListBuffer(31, 96, 20, 12, 52, 56, 25, 11)

  list1 ++=: list2 // list2后面追加list1

  // 4. 修改元素
  list1(3) = 30
  println(list1)
  list2.update(0, 89)
  println(list2)

  // 5. 删除元素
  list2.remove(2)
  list2 -= 25
  println(list2)
}

4 集合

不可变集合:scala.collection.immutable.Set(默认)
可变集合:scala.collection.mutable.Set

4.1 不可变Set

  • Set默认是不可变集合,数据无序
  • 数据不可重复

    def main(args: Array[String]): Unit = {
    // 1. 创建Set
    val set1 = Set(12, 23, 33, 43, 43)
    println(set1) // Set(12, 23, 33, 43),会去重
    
    // 2. 添加元素
    val set2 = set1 + 20
    println(set1) // Set(12, 23, 33, 43)
    println(set2) // Set(20, 33, 12, 43, 23)
    
    // 3. 合并set
    val set3 = Set(19, 13, 23, 53, 67, 99)
    val set4 = set2 ++ set3
    println(set4) // Set(20, 33, 53, 13, 12, 67, 43, 99, 23, 19)
    
    // 4. 删除元素
    val set5 = set3 - 13
    println(set5) // Set(53, 67, 99, 23, 19)
    }
    

    4.2 可变mutable.Set

    def main(args: Array[String]): Unit = {
    // 1. 创建Set
    val set1: mutable.Set[Int] = mutable.Set(13, 23, 43, 421)
    println(set1) // Set(13, 43, 421, 23)
    
    // 2. 添加元素
    val set2 = set1 + 11
    println(set2) // Set(13, 43, 11, 421, 23)
    
    set1 += 11 // 更改了set1本身
    println(set1)
    
    val flag1 = set1.add(10)
    println(flag1) // true
    println(set1) // Set(13, 10, 43, 11, 421, 23)
    val flag2 = set1.add(10)
    println(flag2) // false 再次添加重复元素
    println(set1) // Set(13, 10, 43, 11, 421, 23)
    
    // 3. 删除元素
    set1 -= 11
    println(set1) // Set(13, 10, 43, 421, 23)
    
    val flag3 = set1.remove(10)
    println(flag3) // true
    println(set1) // Set(13, 43, 421, 23)
    
    val flag4 = set1.remove(11)
    println(flag4) // false
    println(set1) // Set(13, 43, 421, 23)
    
    // 4. 合并两个Set
    val set3 = mutable.Set(13, 12, 13, 27 ,98, 29)
    println(set1) // Set(13, 43, 421, 23)
    println(set3) // Set(12, 27, 13, 29, 98)
    val set4 = set1 ++ set3
    println(set1) // Set(13, 43, 421, 23)
    println(set3) // Set(12, 27, 13, 29, 98)
    println(set4) // Set(12, 27, 13, 43, 29, 421, 23, 98)
    
    set1 ++= set3
    println(set1) // Set(12, 27, 13, 43, 29, 421, 23, 98)
    println(set3) // Set(12, 27, 13, 29, 98)
    }
    

    5 Map集合

    是一个散列表,它存储的内容也是键值对(key-value)映射

    5.1 不可变Map

    def main(args: Array[String]): Unit = {
    // 1. 创建map
    val map1: Map[String, Int] = Map("a" -> 13, "b" -> 25, "hello" -> 3)
    println(map1) // Map(a -> 13, b -> 25, hello -> 3)
    println(map1.getClass) // class scala.collection.immutable.Map$Map3
    
    // 2. 遍历元素
    map1.foreach(println)
    /*
    (a,13)
    (b,25)
    (hello,3)
    */
    map1.foreach((kv: (String, Int)) => println(kv))
    
    // 3. 取map中所有的key 或者 value
    for (key <- map1.keys) {
      println(s"$key --> ${map1.get(key)}")
    }
    /*
    a --> Some(13)
    b --> Some(25)
    hello --> Some(3)
    */
    
    // 4. 访问某一个key的value
    println("a: " + map1.get("a").get) // a: 13
    println("c: " + map1.get("c")) // c: None
    println("c: " + map1.getOrElse("c", 0)) // c: 0
    
    println(map1("a")) // 13
    }
    

    5.2 可变Map

    def main(args: Array[String]): Unit = {
    // 1. 创建map
    val map1: mutable.Map[String, Int] = mutable.Map("a" -> 13, "b" -> 25, "hello" -> 3)
    println(map1) // Map(b -> 25, a -> 13, hello -> 3)
    println(map1.getClass) // class scala.collection.mutable.HashMap
    
    // 2. 添加元素
    map1.put("c", 5)
    map1.put("d", 9)
    println(map1) // Map(b -> 25, d -> 9, a -> 13, c -> 5, hello -> 3)
    
    map1 += (("e", 7))
    println(map1) // Map(e -> 7, b -> 25, d -> 9, a -> 13, c -> 5, hello -> 3)
    
    // 3. 删除元素
    println(map1("c")) // 5
    map1.remove("c")
    println(map1.getOrElse("c", 0)) // 0
    
    map1 -= "d"
    println(map1) // Map(e -> 7, b -> 25, a -> 13, hello -> 3)
    
    // 4. 修改元素
    map1.update("c", 6)
    map1.update("e", 10)
    println(map1) // Map(e -> 10, b -> 25, a -> 13, c -> 6, hello -> 3)
    
    // 5. 合并两个Map
    val map2: Map[String, Int] = Map("aaa" -> 13, "b" -> 29, "hello" -> 5 )
    map1 ++= map2 // map2中的值添加到map1里并覆盖
    println(map1) // Map(e -> 10, aaa -> 13, b -> 29, a -> 13, c -> 6, hello -> 5)
    }
    

    6 元组

    理解为一个容器,存放各种相同或不同类型的数据。
    元组中最多只能有22个元素。

    def main(args: Array[String]): Unit = {
    // 1. 创建元组
    val tuple1: (String, Int, Char, Boolean) = ("hello", 10, 'a', true)
    println(tuple1) // (hello,10,a,true)
    
    // 2. 访问数据
    println(tuple1._1) // hello
    println(tuple1._2) // 10
    println(tuple1._3) // a
    println(tuple1._4) // true
    
    println(tuple1.productElement(1)) // 10 ,是从0开始的
    
    // 3. 遍历元组数据
    for (elem <- tuple1.productIterator) {
      println(elem)
    }
    
    // 4. 嵌套元组
    val mulTuple = (12, 0.3, "hello", (23, "scala"), 8)
    println(mulTuple._4._2) // scala
    }
    

    7 集合常用函数

    7.1 基本属性和常用操作

    def main(args: Array[String]): Unit = {
    val list = List(1, 3, 5, 38, 69)
    val set = Set(51, 25, 65, 98, 78)
    // 1. 获取集合长度
    println(list.length)
    
    // 2. 获取集合大小
    println(set.size)
    
    // 3. 循环遍历
    for(elem <- list) {
      println(elem)
    }
    set.foreach(println)
    
    // 4. 迭代器
    for(elem <- list.iterator) {
      println(elem)
    }
    
    // 5. 生成字符串
    println(list)
    println(set)
    println(list.mkString("--"))
    
    // 6. 是否包含
    println(list.contains(11))
    println(list.contains(11))
    }
    

    7.2 衍生集合

    def main(args: Array[String]): Unit = {
    val list1 = List(1, 3, 5, 38, 69)
    val list2 = List(3, 7, 2)
    val set = Set(51, 25, 65, 98, 78)
    // 1. 获取集合的头
    println(list1.head)
    
    // 2. 获取集合的尾
    println(list1.tail) // 去掉头其它都是尾 List(3, 5, 38, 69)
    
    // 3. 集合最后一个
    println(list1.last)
    
    // 4. 集合初始数据(不包含最后一个)
    println(list1.init) // List(1, 3, 5, 38)
    
    // 5. 反转
    println(list1.reverse)
    
    // 6. 取前(后)n个元素
    println(list1.take(3))
    println(list1.takeRight(4))
    
    // 7. 去掉前(后)n个元素
    println(list1.drop(3))
    println(list1.dropRight(4))
    
    // 8. 并集
    val union = list1.union(list2)
    println(union) // List(1, 3, 5, 38, 69, 3, 7, 2)
    // set做并集,会去重
    val set1 = Set(51, 25, 65, 98)
    val set2 = Set(51, 25, 65, 98, 75)
    
    val union2 = set1.union(set2)
    println(union2) // Set(25, 65, 98, 75, 51)
    println(set1 ++ set2) // Set(25, 65, 98, 75, 51)
    
    // 9. 交集
    val intersection = list1.intersect(list2)
    println(intersection) // List(3)
    
    // 10. 差集
    val diff1 = list1.diff(list2) // 属于list1不属于list2
    
    // 11. 拉链 对应位置上的元素构成二元组,多余的无用
    println(list1.zip(list2)) // List((1,3), (3,7), (5,2))
    
    // 12. 滑窗
    println(list1.sliding(3)) // <iterator>
    for (elem <- list1.sliding(3)) {
      println(elem)
    }
    /*
    List(1, 3, 5)
    List(3, 5, 38)
    List(5, 38, 69)
    */
    // 步长为2
    for (elem <- list1.sliding(4, 2)) {
      println(elem)
    }
    /*
    List(1, 3, 5)
    List(3, 5, 38)
    List(5, 38, 69)
    List(1, 3, 5, 38)
    List(5, 38, 69)
    */
    }
    

    7.3 集合计算简单函数

    def main(args: Array[String]): Unit = {
    val list = List(5, 1, 8, 2, -3, 4)
    val list1 = List(("a", 5), ("b", 1), ("c", 8), ("d", 2), ("e", -3), ("f", 4))
    
    // 1. 求和
    var sum = 0
    for (elem <- list) {
      sum += elem
    }
    println(sum) // 17
    println(list.sum) // 17
    
    // 2. 求乘积
    println(list.product)
    
    // 3. 最大值
    println(list.max)
    println(list1.max) // (f,4) 默认判断了字符串的大小
    println(list1.maxBy((tuple: (String, Int)) => tuple._2))
    println(list1.maxBy(_._2))
    
    // 4. 最小值
    println(list.min)
    println(list1.minBy(_._2))
    
    // 5. 排序
    // 5.1 sorted
    val sortedList = list.sorted
    println(sortedList) // List(-3, 1, 2, 4, 5, 8)
    // 从大到小
    println(list.sorted.reverse)
    // 传入隐式参数
    println(list.sorted(Ordering[Int].reverse))
    
    println(list1.sorted) // List((a,5), (b,1), (c,8), (d,2), (e,-3), (f,4))
    
    // 5.2 sortBy
    println(list1.sortBy(_._2)) // List((e,-3), (b,1), (d,2), (f,4), (a,5), (c,8))
    println(list1.sortBy(_._2)(Ordering[Int].reverse)) // List((c,8), (a,5), (f,4), (d,2), (b,1), (e,-3))
    
    // 5.3 sortWith
    println(list.sortWith((a: Int, b: Int) => { a < b })) // List(-3, 1, 2, 4, 5, 8)
    println(list.sortWith( _ < _ ))
    println(list.sortWith( _ > _ ))
    }
    

    7.4 集合计算高级函数

    object Test14_HighLevelFunction_Map {
    def main(args: Array[String]): Unit = {
      val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
      // 1. 过滤
      // 选取偶数
      val evenList = list.filter((elem: Int) => {
        elem % 2 == 0
      })
      println(evenList)
    
      // 选取奇数
      println(list.filter(_ % 2 == 1)) // List(1, 3, 5, 7, 9)
    
      // 2. map
      // 把集合中每个数乘2
      println(list.map(_ * 2)) // List(2, 4, 6, 8, 10, 12, 14, 16, 18)
      println(list.map(x => x * x)) // List(1, 4, 9, 16, 25, 36, 49, 64, 81)
    
      // 3. 扁平化
      val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 5), List(6, 7, 8, 9))
      val flatList = nestedList(0) ::: nestedList(1) ::: nestedList(2)
      println(flatList) // List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
      val flatList2 = nestedList.flatten
      println(flatList2) // List(1, 2, 3, 4, 5, 6, 7, 8, 9)
    
      // 4. 扁平映射
      // 将一组字符串进行分词,并保存成单词的列表
      val strings: List[String] = List("hello world", "hello scala")
      val splitList: List[Array[String]] = strings.map(string => string.split(" ")) // 分词
      val flattenList = splitList.flatten // 打散扁平化
      println(flattenList) // List(hello, world, hello, scala)
    
      val flatmapList = strings.flatMap(_.split(" "))
    
      // 5. 分组groupBy
      // 分成奇偶两组
      val groupMap: Map[Int, List[Int]] = list.groupBy(_ % 2)
      val groupMap1 = list.groupBy(data => {
        if(data%2 == 0) "偶数" else "奇数"
      })
      println(groupMap) // Map(1 -> List(1, 3, 5, 7, 9), 0 -> List(2, 4, 6, 8))
      println(groupMap1) // Map(奇数 -> List(1, 3, 5, 7, 9), 偶数 -> List(2, 4, 6, 8))
    
      // 给定一组词汇,按照单词的首字母进行分组
      val wordList = List("cdfs","wdasd","adads","dasad","adqw")
      println(wordList.groupBy(_.charAt(0))) // Map(c -> List(cdfs), w -> List(wdasd), a -> List(adads, adqw), d -> List(dasad))
    }
    }
    
    object Test15_HighLevelFunction_Reduce {
    def main(args: Array[String]): Unit = {
      val list = List(1, 2, 3, 4)
      // 1. reduce
      println(list.reduce(_ + _)) // sum
      println(list.reduceLeft(_ + _)) // 从左往右加
      println(list.reduceRight(_ + _)) // 从右往左加
    
      val list2 = List(3, 4, 5, 8, 10)
      println(list2.reduce(_ - _)) // -24
      println(list2.reduceLeft(_ - _)) // -24 reduce底层是reduceLeft
      /*
      override /*IterableLike*/
      def reduceRight[B >: A](op: (A, B) => B): B =
      if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight")
      else if (tail.isEmpty) head
      else op(head, tail.reduceRight(op))
      3-(4-(5-(8-10))) = 6
      */
      println(list2.reduceRight(_ - _)) // 6
    
    }
    }
    
    object Test15_HighLevelFunction_Reduce {
    def main(args: Array[String]): Unit = {
      val list = List(1, 2, 3, 4)
      // 1. reduce
      println(list.reduce(_ + _)) // sum
      println(list.reduceLeft(_ + _)) // 从左往右加
      println(list.reduceRight(_ + _)) // 从右往左加
    
      val list2 = List(3, 4, 5, 8, 10)
      println(list2.reduce(_ - _)) // -24
      println(list2.reduceLeft(_ - _)) // -24 reduce底层是reduceLeft
      /*
      override /*IterableLike*/
      def reduceRight[B >: A](op: (A, B) => B): B =
        if (isEmpty) throw new UnsupportedOperationException("Nil.reduceRight")
        else if (tail.isEmpty) head
        else op(head, tail.reduceRight(op))
        3-(4-(5-(8-10))) = 6
       */
      println(list2.reduceRight(_ - _)) // 6
    
      // 2. fold
      // 第一个参数 初始值,第二个参数 简化规则
      println(list.fold(10)(_ + _)) // 10 + 1 + 2 + 3 + 4 = 20
      println(list.foldLeft(10)(_ - _)) // 10 - 1 - 2 - 3 - 4 = 0
      /*
      override def foldRight[B](z: B)(op: (A, B) => B): B =
        reverse.foldLeft(z)((right, left) => op(left, right))
       */
      println(list2.foldRight(11)(_ - _)) // 3 - (4 - (5 - (8 - (10 - 11)))) = -5
    }
    }
    
    object Test16_MergeMap {
    def main(args: Array[String]): Unit = {
      val map1 = Map("a" -> 1, "b" -> 3, "c"  -> 6)
      val map2 = mutable.Map("a" -> 6, "b" -> 2, "c" -> 9, "d" -> 3)
    
      val map3 = map1.foldLeft(map2)(
        (mergedMap,kv) =>{
          val key = kv._1
          val value = kv._2
          mergedMap(key) = mergedMap.getOrElse(key, 0) + value
          mergedMap
        }
      )
      println(map3) // Map(b -> 5, d -> 3, a -> 7, c -> 15)
    }
    }
    

    7.5 普通WordCount案例

    object Test17_CommonWordCount {
    def main(args: Array[String]): Unit = {
      val stringList = List("Hello Scala Hbase kafka", "Hello Scala Hbase", "Hello Scala", "Hello")
    
      // 1. 对字符串进行切分,得到一个打散所有单词的列表
      //    val wordList1: List[Array[String]] = stringList.map(_.split(" "))
      //    val wordList2: List[String] = wordList1.flatten
      //    println(wordList2)
      val wordList = stringList.flatMap(_.split(" "))
      println(wordList) // List(Hello, Scala, Hbase, kafka, Hello, Scala, Hbase, Hello, Scala, Hello)
    
      // 2. 相同的单词进行分组
      val groupMap: Map[String, List[String]] = wordList.groupBy(word => word)
      println(groupMap) // Map(Hello -> List(Hello, Hello, Hello, Hello), Scala -> List(Scala, Scala, Scala), Hbase -> List(Hbase, Hbase), kafka -> List(kafka))
    
      // 3. 对分组之后的list取长度,得到每个单词的个数
      val countMap: Map[String, Int] = groupMap.map(kv => (kv._1, kv._2.length))
    
      // 4. 将map转换为list,排序取前3
      val sortList: List[(String, Int)] = countMap.toList.sortWith(_._2 > _._2).take(3)
      println(sortList) // List((Hello,4), (Scala,3), (Hbase,2))
    }
    }
    

    7.6 复杂WordCount

    object Test18_ComplexWordCount {
    def main(args: Array[String]): Unit = {
      val tupleList = List(("Hello Scala Spark World ", 4), ("Hello Scala Spark", 3), ("Hello Scala", 2), ("Hello", 1))
      // 方式一:直接展开为普通版本
      val newStringList: List[String] = tupleList.map(
        kv => {
          (kv._1.trim + " ") * kv._2
        }
      )
      // 剩余的操作和Test17一样
      val wordCountList: List[(String, Int)] = newStringList
        .flatMap(_.split(" "))
        .groupBy(word => word)
        .map(kv => (kv._1, kv._2.size))
        .toList
        .sortBy(_._2)(Ordering[Int].reverse)
        .take(3)
      println(wordCountList) // List((Hello,10), (Scala,9), (Spark,7))
    
      // 方式二:直接基于预统计的结果进行转换
      // 1. 将字符串打散为单词
      val preCountList: List[(String, Int)] = tupleList.flatMap(
        tuple => {
          val strings: Array[String] = tuple._1.split(" ")
          strings.map(word => (word, tuple._2))
        }
      )
      println(preCountList) // List((Hello,4), (Scala,4), (Spark,4), (World,4), (Hello,3), (Scala,3), (Spark,3), (Hello,2), (Scala,2), (Hello,1))
    
      // 2. 对二元组按照单词进行分组
      val preCountMap: Map[String, List[(String, Int)]] = preCountList.groupBy(_._1)
      println(preCountMap)
    
      // 3. 叠加每个单词预统计的个数值
      val countMap: Map[String, Int] = preCountMap.mapValues(
        tupleList => tupleList.map(_._2).sum
      )
      println(countMap) // Map(Hello -> 10, Scala -> 9, Spark -> 7, World -> 4)
    
      // 4. 转换成list,排序取前三
      val countList = countMap.toList.sortWith(_._2 > _._2).take(3)
      println(countList) // List((Hello,10), (Scala,9), (Spark,7))
    }
    }
    

    7.8 队列

    object Test19_Queue {
    def main(args: Array[String]): Unit = {
      // 创建一个可变队列
      val queue: mutable.Queue[String] = new mutable.Queue[String]()
    
      queue.enqueue("a", "b", "c")
      println(queue) // Queue(a, b, c)
      println(queue.dequeue())
      println(queue) // Queue(b, c)
    
      // 不可变队列
      val queue2 = Queue("a", "b", "c")
      val queue3 = queue2.enqueue("d")
      println(queue2) // Queue(a, b, c)
      println(queue3) // Queue(a, b, c, d)
    }
    }
    

    7.9 并行集合

    为了充分使用多核CPU,提供并行集合

    object Test20_Parallel {
    def main(args: Array[String]): Unit = {
      val result: immutable.IndexedSeq[Long] = (1 to 100).map(
        x => Thread.currentThread.getId
      )
      println(result) // Vector(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
    
      val result2 = (1 to 100).par.map(
        x => Thread.currentThread.getId
      )
      println(result2) // ParVector(20, 20, 20, 20, 20, 20, 30, 30, 30, 30, 30, 30, 26, 26, 26, 26, 26, 26, 33, 33, 33, 33, 33, 33, 33, 22, 22, 22, 22, 22, 22, 34, 34, 34, 34, 34, 34, 25, 25, 25, 32, 34, 24, 31, 31, 31, 31, 31, 31, 31, 21, 21, 21, 32, 32, 32, 28, 28, 28, 21, 28, 31, 24, 24, 24, 24, 24, 24, 29, 29, 29, 29, 29, 29, 29, 23, 23, 23, 23, 23, 23, 33, 24, 33, 26, 32, 22, 27, 27, 27, 27, 27, 27, 35, 35, 35, 35, 35, 35, 35)
    }
    }