Scala笔记--集合与流式处理

文章目录

  • 1 常用集合类型
    • 1.1 数组
      • 1.1.1 不可变数组Array
      • 1.1.2 可变数组ArrayBuffer
      • 1.1.3 多维数组
    • 1.2 列表
      • 1.2.1 不可变列表List
      • 1.2.2 可变列表ListBuffer
    • 1.3 Set
      • 1.3.1 不可变Set
      • 1.3.2 可变Set
    • 1.4 map
      • 1.4.1 不可变map
      • 1.4.2 可变Map
    • 1.5 tuple
    • 1.6 栈与队列
  • 2 集合常用操作
    • 2.1 集合基础操作
    • 2.2 衍生集合
    • 2.3 计算函数
    • 2.4 高级函数
    • 2.5 scala实现WordCount案例一
    • 2.6 scala实现WordCount案例二
    • 2.7 scala实现WordCount案例三
  • 3 并行流

Scala推崇不可变集合,尽管也可以使用可变版本。如果想要修改集合,而且集合上所有的操作都在单线程中进行,那么就可以选择可变集合。但是,如果打算跨线程、跨Actor地使用集合,那么不可变集合将会是更好的选择。不可变集合是线程安全的,不受副作用影响,并且有助于程序的正确性。 可以通过选择下列两个包之一来选择所使用的版本:scala.collection.mutable或者scala.collection.immutable。如果不指定所使用的包名,那么,在默认情况下,Scala会使用不可变集合

1 常用集合类型

1.1 数组

1.1.1 不可变数组Array

主要操作包括创建数组、访问数组元素、修改数组元素、数组遍历、添加元素

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 1:21
 * @description 不可变数组
 */
object demo1 {
     
  def main(args: Array[String]): Unit = {
     
    // 1.创建数组方式一
    val arr1: Array[Int] = new Array[Int](5)
    // 创建数组方式二,使用伴生对象的Apply方法
    val arr2: Array[Int] = Array(1, 2, 3, 4, 5)

    // 2. 访问数组元素、修改数组元素
    println(arr1(0))
    println(arr1(4))
    println("========================")
    arr2(0) = 10
    arr2(4) = 12
    println(arr2(0))
    println(arr2(4))
    println("========================")

    // 3.数组遍历
    // 3.1 普通for循环
    for (i <- 0 until arr2.length) {
     
      print(arr2(i) + "\t")
    }
    println()
    // 3.2 根据索引方法
    for (i <- arr2.indices)
      print(arr2(i) + "\t")
    println()

    // 3.3 增强for循环
    for (item <- arr2)
      print(item + "\t")
    println()

    // 3.4 使用foreach方法
    arr2.foreach((item: Int) => print(item + "\t"))
    println()
    arr2.foreach(println)
    println("========================")

    // 4. 添加元素
    val newArr = arr2.:+(73)
    println(arr2.mkString("-"))
    println(newArr.mkString("-"))

    val newArr2 = newArr.+:(30)
    println(newArr2.mkString("-"))

    val newArr3 = newArr2 :+ 15
    val newArr4 = 19 +: 29 +: newArr3 :+ 26 :+ 73
    println(newArr4.mkString("-"))
  }
}

1.1.2 可变数组ArrayBuffer

可变数组与不可变数组在操作上基本是一致的。主要区别在于增加元素和删除元素上。

package com.lrm.demo07


import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 13:20
 * @description 可变数组
 */
object demo2 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建可变数组
    val arr1: ArrayBuffer[Int] = new ArrayBuffer[Int]()
    val arr2 = ArrayBuffer(11, 22, 33)
    println(arr1)
    println(arr2)
    println("======================")

    // 2. 访问元素
    println(arr2(1))
    arr2(1) = 28
    println(arr2(1))
    println("======================")

    // 3. 添加元素
    val newArr1 = arr1 += 19
    println(arr1)
    println(newArr1)
    println(arr1 == newArr1)
    newArr1 += 13
    println(arr1)
    println("======================")

    77 +=: arr1
    println(arr1)
    println(newArr1)
    println("======================")

    arr1.append(36)
    arr1.prepend(11, 76)
    arr1.insert(1, 13, 59)  // 在索引1上插入12,59
    println(arr1)
    println("======================")

    arr1.insertAll(2, newArr1)
    arr1.prependAll(newArr1)
    println(arr1)
    println("======================")

    // 4. 删除元素
    arr1.remove(3)
    println(arr1)
    arr1.remove(0, 10)
    println(arr1)
    println("======================")

    arr1 -= 13
    println(arr1)
    println("======================")

    // 5. 可变数组转换为不可变数组
    val arr: ArrayBuffer[Int] = ArrayBuffer(23, 56, 98)
    val newArr: Array[Int] = arr.toArray
    println(newArr.mkString(", "))
    println(arr)

    // 6. 不可变数组转换为可变数组
    val buffer: mutable.Buffer[Int] = newArr.toBuffer
    println(buffer)
    println(newArr)
  }
}

1.1.3 多维数组

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 14:28
 * @description 多维数组
 */
object demo3 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建二维数组,2行3列
    val array: Array[Array[Int]] = Array.ofDim[Int](2, 3)

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

    println(array.mkString(", "))
    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))
  }
}

1.2 列表

1.2.1 不可变列表List

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 14:29
 * @description 不可变List
 */
object demo4 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建一个List,List是一个抽象类
    val list1 = List(23, 65, 87)
    println(list1)
    println("==================")

    // 2. 访问和遍历元素
    println(list1(1))
    list1.foreach(println)
    println("==================")

    // 3. 添加元素
    val list2 = 10 +: list1
    val list3 = list1 :+ 23
    val list4 = list2.::(51)
    val list5 = Nil.::(13)
    val list6 = 73 :: 32 :: Nil
    val list7 = 17 :: 28 :: 59 :: 16 :: Nil
    println(list1)
    println(list2)
    println(list3)
    println(list4)
    println(list5)
    println(list6)
    println(list7)
    println("==================")

    // 4. 合并列表
    val list8 = list6 :: list7    // 合并整个list
    println(list8)
    val list9 = list6 ::: list7   // 合并所有元素
    println(list9)
    val list10 = list6 ++ list7     // 合并所有元素
    println(list10)
  }
}

1.2.2 可变列表ListBuffer

package com.lrm.demo07

import scala.collection.mutable.ListBuffer

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 16:45
 * @description 可变List
 */
object demo5 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建可变列表
    val list1: ListBuffer[Int] = new ListBuffer[Int]()
    val list2 = ListBuffer(12, 53, 75)
    println(list1)
    println(list2)
    println("==============")

    // 2. 添加元素
    list1.append(15, 62)
    list2.prepend(20)
    list1.insert(1, 19, 22)
    println(list1)
    println(list2)

    31 +=: 96 +=: list1 += 25 += 11
    println(list1)
    println("==============")


    // 3. 合并list
    val list3 = list1 ++ list2
    println(list1)
    println(list2)
    println(list3)
    println("==============")

    list1 ++=: list2
    println(list1)
    println(list2)
    println(list3)

    println("==============")

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

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

1.3 Set

1.3.1 不可变Set

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 17:04
 * @description 不可变Set
 */
object demo6 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建set
    val set1 = Set(13, 23, 53, 12, 13, 23, 78)
    println(set1)
    println("==================")

    // 2. 添加元素
    val set2 = set1 + 129
    println(set1)
    println(set2)
    println("==================")

    // 3. 合并set
    val set3 = Set(19, 13, 23, 53, 67, 99)
    val set4 = set2 ++ set3
    println(set2)
    println(set3)
    println(set4)
    println("==================")

    // 4. 删除元素
    val set5 = set3 - 13
    println(set3)
    println(set5)
    println("==================")
  }
}

1.3.2 可变Set

package com.lrm.demo07

import scala.collection.mutable
import scala.collection.mutable.Set

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 17:10
 * @description 可变Set
 */
object demo7 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建set
    val set1: Set[Int] = Set(13, 23, 53, 12, 13, 23, 78)
    println(set1)
    println("==================")

    // 2. 添加元素
    val set2 = set1 + 11
    println(set1)
    println(set2)
    println(set1 == set2)
    set1 += 11
    println(set1)
    println(set1 == set2)
    println("==================")

    val flag1 = set1.add(10)
    println(flag1)
    println(set1)
    val flag2 = set1.add(10)
    println(flag2)
    println(set1)
    println("==================")

    // 3. 删除元素
    set1 -= 11
    println(set1)
    val flag3 = set1.remove(10)
    println(flag3)
    println(set1)
    val flag4 = set1.remove(10)
    println(flag4)
    println(set1)
    println("==================")

    // 4. 合并两个Set
    val set3 = Set(99,88)
    println(set1)
    println(set3)
    println("==================")
    val set4: Set[Int] = set1 ++ set3
    println(set1)
    println(set3)
    println(set4)
    println("==================")
    set1 ++= set3
    println(set1)
    println(set3)
    println("==================")
  }
}

1.4 map

1.4.1 不可变map

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 17:29
 * @description
 */
object demo8 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建map
    val map1: Map[String, Int] = Map("a" -> 13, "b" -> 25, "hello" -> 3)
    println(map1)
    println(map1.getClass)
    println("==========================")

    // 2. 遍历元素
    map1.foreach(print)
    println()
    map1.foreach((kv: (String, Int)) => print(kv))
    println()
    println("============================")

    // 3. 取map中所有的key 或者 value
    for (key <- map1.keys) {
     
      println(s"$key ---> ${map1.get(key)}")
    }
    println("============================")
    
    // 4. 访问某一个key的value
    println("a: " + map1.get("a"))
    println("a: " + map1.get("a").get)
    println("c: " + map1.get("c"))
    println("c: " + map1.getOrElse("b", 0))
    println("c: " + map1.getOrElse("c", 0))
    println(map1("a"))
  }
}

1.4.2 可变Map

package com.lrm.demo07

import scala.collection.mutable

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 17:44
 * @description
 */
object demo9 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建map
    val map1: mutable.Map[String, Int] = mutable.Map("a" -> 13, "b" -> 25, "hello" -> 3)
    println(map1)
    println(map1.getClass)
    println("==========================")

    // 2. 添加元素
    map1.put("c", 5)
    map1.put("d", 9)
    println(map1)
    map1 += (("e", 7))
    println(map1)
    println("====================")

    // 3. 删除元素
    map1.remove("c")
    println(map1)
    map1 -= "d"
    println(map1)
    println("====================")

    // 4. 修改元素
    map1.update("c", 5)
    map1.update("e", 10)
    println(map1)
    println("====================")

    // 5. 合并两个Map
    val map2: Map[String, Int] = Map("aaa" -> 11, "b" -> 29, "hello" -> 5)
    println(map1)
    map1 ++= map2
    println(map1)
    println(map2)
    println("====================")

    val map3: Map[String, Int] = map2 ++ map1
    println(map1)
    println(map2)
    println(map3)
  }
}

1.5 tuple

包含4个元素的元组的类叫做Tuple4,Scala支持Tuple1-Tuple22

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 17:54
 * @description 元祖
 */
object demo10 {
     
  def main(args: Array[String]): Unit = {
     
    // 1. 创建元组
    val tuple: (String, Int, Char, Boolean) = ("hello", 100, 'a', true)
    println(tuple)
    println(tuple.getClass)
    println("====================")

    // 2. 访问数据
    println(tuple._1)
    println(tuple._2)
    println(tuple._3)
    println(tuple._4)
    println(tuple.productElement(1))
    println("====================")

    // 3. 遍历元组数据
    for (elem <- tuple.productIterator)
      println(elem)
    println("====================")

    // 4. 嵌套元组
    val mulTuple = (12, 0.3, "hello", (23, "scala"), 29)
    println(mulTuple._4._2)
  }
}

1.6 栈与队列

package com.lrm.demo07

import scala.collection.immutable.Queue
import scala.collection.mutable
/**
 * @author RuiMing Lin 
 * @date 2021-06-04 20:44
 * @description
 */
object demo18 {
     
  def main(args: Array[String]): Unit = {
     
    // 可变队列
    val queue: mutable.Queue[String] = new mutable.Queue[String]()
    queue.enqueue("a", "b", "c")
    println(queue)
    println(queue.dequeue())
    println(queue)
    println(queue.dequeue())
    println(queue)
    queue.enqueue("d", "e")
    println(queue)
    println(queue.dequeue())
    println(queue)
    println("==========================")

    // 不可变队列
    val queue2: Queue[String] = Queue("a", "b", "c")
    val queue3 = queue2.enqueue("d")
    println(queue2)
    println(queue3)

    val stack: mutable.Stack[String] = mutable.Stack[String]()
  }
}

2 集合常用操作

2.1 集合基础操作

基础操作和Java的集合操作基本一致,主要操作包括获取集合长度、遍历集合、集合迭代器操作、包含函数

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 18:02
 * @description
 */
object demo11 {
     
  def main(args: Array[String]): Unit = {
     
    val list = List(1, 3, 5, 7, 2, 89)
    val set = Set(23, 34, 423, 75)

    // 1.获取集合长度,IndexedSeq的子类才有的属性
    println(list.length)
    println("====================")

    // 2.获取集合大小
    println(list.size)
    println(set.size)
    println("====================")

    // 3.循环遍历
    for (elem <- list)
      println(elem)
//    set.foreach(println)
    println("====================")

    // 4.迭代器
    for (elem <- list.iterator) println(elem)
    val iterator: Iterator[Int] = list.iterator
    while (iterator.hasNext) {
     
      println(iterator.next())
    }
    println("====================")

    // 5.生成字符串
    println(list.mkString(" "))
    println(set.mkString(" "))
    println("====================")

    // 6.是否包含
    println(list.contains(23))
    println(set.contains(23))
  }
}

2.2 衍生集合

此部分函数主要是对原集合进行衍生,如子集或者超集

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 18:16
 * @description 衍生集合
 */
object demo12 {
     
  def main(args: Array[String]): Unit = {
     
    val list1 = List(1, 3, 5, 7, 2, 89)
    val list2 = List(3, 7, 2, 45, 4, 8, 19)

    // 1.获取集合的头
    println(list1.head)
    println("=========================")

    // 2.获取集合的尾  不是头的就是尾
    println(list1.tail)
    println("=========================")

    // 3.最后一个数据
    println(list2.last)
    println("=========================")

    // 4.不包含最后一个
    println(list2.init)
    println("=========================")

    // 5.反转
    println(list1.reverse)
    println("=========================")

    // 6.取前后n个元素
    println(list1.take(3))
    println(list1.takeRight(4))
    println("=========================")

    // 7.去掉前后n个元素
    println(list1.drop(3))
    println(list1.dropRight(4))
    println("=========================")

    // 8.并集
    val union = list1.union(list2)
    println("union: " + union)
    println(list1 ::: list2)
    println("=========================")

    // 如果是set做并集,会去重(与数学上的并集一样)
    val set1 = Set(1, 3, 5, 7, 2, 89)
    val set2 = Set(3, 7, 2, 45, 4, 8, 19)
    val union2 = set1.union(set2)
    println("union2: " + union2)
    println(set1 ++ set2)
    println("=========================")

    // 9 交集,与数学上的交集一样
    val intersection = list1.intersect(list2)
    println("intersection: " + intersection)
    println("=========================")

    // 10 差集,与数学上的差集一样
    val diff1 = list1.diff(list2)
    val diff2 = list2.diff(list1)
    println("diff1: " + diff1)
    println("diff2: " + diff2)
    println("=========================")

    // 11 zip,和python的zip函数类似
    println("zip: " + list1.zip(list2))
    println("zip: " + list2.zip(list1))
    println("=========================")

    // 12 滑窗
    for (elem <- list1.sliding(3))
      println(elem)
    println("=========================")
    for (elem <- list2.sliding(4, 2))
      println(elem)
    println("=========================")
    for (elem <- list2.sliding(3, 3))
      println(elem)
  }
}

2.3 计算函数

主要操作包括求和、点乘、最值、排序

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 18:44
 * @description
 */
object demo13 {
     
  def main(args: Array[String]): Unit = {
     
    val list = List(5, 1, 8, 2, -3, 4)
    val list2: List[(String, Int)] = List(("a", 5), ("b", 1), ("c", 8), ("d", 2), ("e", -3), ("f", 4))

    // 1 .求和
    println(list.sum)
    println("=========================")

    // 2 .求乘积
    println(list.product)
    println("=========================")

    // 3 .最大值
    println(list.max)
    println(list2.maxBy((tuple: (String, Int)) => tuple._2))
    println(list2.maxBy(_._2))
    println("=========================")

    // 4 .最小值
    println(list.min)
    println(list2.minBy(_._2))
    println("=========================")

    // 5 .排序
    // 5.1 sorted
    println(list.sorted)
    // 逆序排序,效率较低
    println(list.sorted.reverse)
    // 传入隐式参数
    println(list.sorted(Ordering[Int].reverse))
    println("=========================")

    // 5.2 sortBy
    println(list2.sortBy(_._2))
    println(list2.sortBy(_._2)(Ordering[Int].reverse))
    println("=========================")

    // 5.3 sortWith
    println(list.sortWith((a: Int, b: Int) => {
     
      a < b
    }))
    println(list.sortWith(_ < _))
    println(list.sortWith(_ > _))
  }
}

2.4 高级函数

此部分函数与Java8新特性基本一致(其实是Java8流式处理借鉴了scala的函数式编程)。主要操作包括filter、map、flatten、flatMap、groupBy、reduce、fold

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 19:02
 * @description
 */
object demo14 {
     
  def main(args: Array[String]): Unit = {
     
    val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
    // 1. 过滤
    // 选取偶数
    val evenList = list.filter((elem: Int) => {
     
      elem % 2 == 0
    })
    println(evenList)
    // 选取奇数
    println(list.filter(_ % 2 == 1))
    println("=======================")

    // 2. map
    println(list.map(_ * 2))
    println(list.map(x => x * x))
    println("=======================")

    // 3. flatten
    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)

    val flatList2 = nestedList.flatten
    println(flatList2)
    println("=======================")

    // 4. flatMap:先map再flatten
    val strings: List[String] = List("hello world", "hello scala", "hello java", "hello hadoop")
    val splitList: List[Array[String]] = strings.map(_.split(" ")) // 分词
    val flattenList = splitList.flatten // 打散扁平化
    println(flattenList)

    val flatmapList = strings.flatMap(_.split(" "))
    println(flatmapList)
    println("========================")

    // 5. 分组groupBy
    // 分成奇偶两组
    val groupMap: Map[Int, List[Int]] = list.groupBy(_ % 2)
    val groupMap2: Map[String, List[Int]] = list.groupBy(data => if (data % 2 == 0) "偶数" else "奇数")
    println(groupMap)
    println(groupMap2)
    // 给定一组词汇,按照单词的首字母进行分组
    val wordList = List("china", "america", "alice", "canada", "cary", "bob", "japan")
    println(wordList.groupBy(_.charAt(0)))
    println("===========================")

    // 6. reduce
    val numbers1: List[Int] = List(1, 2, 3, 4)
    println(numbers1.reduce(_ + _))
    println(numbers1.reduceLeft(_ + _))
    println(numbers1.reduceRight(_ + _))
    println("===========================")

    val numbers2 = List(3, 4, 5, 8, 10)
    println(numbers2.reduce(_ - _)) // -24
    println(numbers2.reduceLeft(_ - _))
    println(numbers2.reduceRight(_ - _)) // 3 - (4 - (5 - (8 - 10))), 6
    println("===========================")

    // 7. fold
    println(numbers1.fold(10)(_ + _)) // 10 + 1 + 2 + 3 + 4
    println(numbers1.foldLeft(10)(_ - _)) // 10 - 1 - 2 - 3 - 4
    println(numbers2.foldRight(11)(_ - _)) // 3 - (4 - (5 - (8 - (10 - 11)))),  -5
  }
}

2.5 scala实现WordCount案例一

WordCount是大数据领域的Helloworld

package com.lrm.demo07

import scala.collection.mutable

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 19:54
 * @description
 */
object demo15 {
     
  def main(args: Array[String]): Unit = {
     
    // "hello" -> 1表示hello出现1次
    val map1: Map[String, Int] = Map("hello" -> 1, "hi" -> 3, "yes" -> 6)
    val map2: mutable.Map[String, Int] = mutable.Map("hello" -> 6, "hi" -> 2, "yes" -> 9, "no" -> 3)

    // 以map2为初始map,每次返回新的tempMap。必须使用foldLeft,因为map2的类型和map1不同。
    val resultMap: mutable.Map[String, Int] = map1.foldLeft(map2)(
      (tempMap, kv) => {
         //  tempMap初始值为map2,而后是每一次迭代的结果。kv是map1每一次迭代的kv键值对
        val key: String = kv._1
        val value: Int = kv._2
        tempMap(key) = tempMap.getOrElse(key, 0) + value
        tempMap
      }
    )
    println(resultMap)
  }
}

2.6 scala实现WordCount案例二

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 20:24
 * @description
 */
object demo16 {
     
  def main(args: Array[String]): Unit = {
     
    val stringList: List[String] = List(
      "hello",
      "hello world",
      "hello scala",
      "hello spark from scala",
      "hello flink from scala"
    )

    // 1. 对字符串进行切分,并展平
    val wordList:List[String] = stringList.flatMap(_.split(" "))
//    println(wordList)

    // 2. 相同的单词进行分组
    val groupMap: Map[String, List[String]] = wordList.groupBy(word => word)
//    val groupMap: Map[String, List[String]] = wordList.groupBy(_+"")
//    println(groupMap)

    // 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)
  }
}

2.7 scala实现WordCount案例三

package com.lrm.demo07

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 20:31
 * @description
 */
object demo17 {
     
  def main(args: Array[String]): Unit = {
     
    val tupleList: List[(String, Int)] = List(
      ("hello", 1),
      ("hello world", 2),
      ("hello scala", 3),
      ("hello spark from scala", 1),
      ("hello flink from scala", 2)
    )

    // 方法一
    val newStringList: List[String] = tupleList.map(
      kv => {
     
        (kv._1.trim + " ") * kv._2
      }
    )

    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)
    println("================================")

    // 方法二:
    // 1. 将字符串打散为单词,并结合对应的个数包装成二元组
    val preCountList: List[(String, Int)] = tupleList.flatMap(
      tuple => {
     
        val strings: Array[String] = tuple._1.split(" ")
        strings.map(word => (word, tuple._2))
      }
    )
//    println(preCountList)

    // 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)

    // 4. 转换成list,排序取前3
    val countList = countMap.toList
      .sortWith(_._2 > _._2)
      .take(3)
    println(countList)
  }
}

3 并行流

对于每种类型的容器,Scala都提供了一批相同的方法,实现了丰富的容器操作,基本覆盖了实际需求中大部分的容器问题,只需几个简单的函数调用就可以代替复杂的循环或递归。更重要的是,类库里的基本操作都是经过优化的,因此,使用类库提供的标准操作,通常比自己写的循环更加高效,而且,容器类库已经支持在多核处理器上并行运算。

对于许多顺序集合,Scala都拥有其并行版本。例如,ParArray是Array对应的并行版本,同样的,ParHashMap、ParHashSet和ParVector分别对应于HashMap、HashSet和Vector。我们可以使用par()和seq()方法来在顺序集合及其并行版本之间进行相互转换。

package com.lrm.demo07

import scala.collection.immutable
import scala.collection.parallel.immutable.ParSeq

/**
 * @author RuiMing Lin 
 * @date 2021-06-04 20:51
 * @description
 */
object demo19 {
     
  def main(args: Array[String]): Unit = {
     
    // 串行流,只在main方法的线程中执行
    val result1: immutable.IndexedSeq[String] = (1 to 100).map(
      x => Thread.currentThread.getName
    )
    println(result1)


    // 并行流,会开启多个线程执行
    val result2: ParSeq[String] = (1 to 100).par.map(
      x => Thread.currentThread.getName
    )
    println(result2)
    println("=======================================")

//    val list: List[Int] = List.range(1, 100000000)
    val list: List[Int] = (1 to 10000000).toList
    val start1: Long = System.currentTimeMillis()
    list.map(_ * 2)
    val end1: Long = System.currentTimeMillis()
    println(end1 - start1)


    val start2: Long = System.currentTimeMillis()
    list.par.map(_ * 2)
    val end2: Long = System.currentTimeMillis()
    println(end2 - start2)
  }
}

你可能感兴趣的:(Spark,scala,集合)