大数据之Scala 集合 完整使用(第七章)

大数据之Scala 集合 完整使用

一、集合简介

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

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

不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable

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

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

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

1、不可变集合继承图

大数据之Scala 集合 完整使用(第七章)

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 是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找

2、可变集合继承图

大数据之Scala 集合 完整使用(第七章)

二、数组

1、不可变数组

1)第一种方式定义数组

定义:val arr1 = new ArrayInt
(1)new 是关键字
(2)[Int]是指定可以存放的数据类型,如果希望存放任意数据类型,则指定 Any
(3)(10),表示数组的大小,确定后就不可以变化

2)案例实操

package chapter07

/**
 * 创建数组
 * 在 Scala 中推荐不可变数组
 */
object Test01_ImmutableArray {
  def main(args: Array[String]): Unit = {
    //1、创建数组
    val arr: Array[Int] = new Array[Int](5)

    //另一种创建方式
    val arr2 = Array(12, 32, 23, 13, 16)

    //2、访问和修改元素
    println(arr(0))
    println(arr(1))
    println(arr(4))

    println("++++++++++++++++++++++++++++++++++")
    arr(0) = 12
    arr(4) = 57

    println(arr(0))
    println(arr(1))
    println(arr(4))


    //3、数组的遍历
    //3.1 普通的for循环 ->until 不包含
    for (i <- 0 until arr.length) {
      println(arr(i))
    }
    println("+++++++++++++++普通的for循环+++++++++++++++++++")
    for (i <- arr.indices) {
      println(arr(i))
    }

    //3.2直接便利所有元素、增强for循环
    println("+++++++++++++++增强for循环+++++++++++++++++++")
    for (elem <- arr2) {
      println(elem)
    }

    // 3) 迭代器
    println("+++++++++++++++迭代器+++++++++++++++++++")
    val iterator = arr2.iterator
    while (iterator.hasNext)
      println(iterator.next())

    println("+++++++++++++++调用foreach+++++++++++++++++++")
    //4、调用foreach 方法
    arr2.foreach((elem: Int) => {
      println(elem)
    })

    println("+++++++++++++++调用foreach2+++++++++++++++++++")
    arr2.foreach(println)

    //拼接字符串
    println(arr2.mkString("--"))

    println("--------------添加元素------------------------")
    //5、添加元素
    val newArray1 = arr2.:+(73) // .:+ 代表追加末尾
    println(arr2.mkString("--")) //因为不可变所以不会加进去

    println(newArray1.mkString("--")) //可以返回一个新数组展示

    val newArray2 = newArray1.+:(30) //.+: 代表追加前面
    println(newArray2.mkString("--"))


    val newArray3 = newArray2 :+ 30 //.+: 代表追加前面

    /**
     * TODO
     * 1、.:+ 代表追加末尾
     * 2、.+: 代表追加前面
     */
    val newArray4 = 19 +: 29 +: newArray3 :+ 26 :+ 73
    println(newArray4.mkString("--"))
  }
}

3)第二种方式定义数组

val arr1 = Array(1, 2)
(1)在定义数组时,直接赋初始值
(2)使用 apply 方法创建数组对象

4)案例实操

object TestArray{
 def main(args: Array[String]): Unit = {
 var arr02 = Array(1, 3, "bobo")
 println(arr02.length)
 for (i <- arr02) {
 println(i)
 }
 } }

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 方法(),支持可变参数

package chapter07

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

/**
 * 数组、可变数组
 *
 */
object Test02_ArrayBuffer {
  def main(args: Array[String]): Unit = {
    //TODO 1、创建可变数组
    println("--------TODO 1、创建可变数组-----------------")
    val arr1: ArrayBuffer[Int] = new ArrayBuffer[Int]()
    val arr2 = ArrayBuffer(23, 44, 66, 77, 31)

    println(arr1)
    println(arr1.mkString(","))
    println(arr2)

    println("--------TODO 2、访问元素-----------------")
    //TODO 2、访问元素
    println(arr2(1))
    arr2(1) = 39
    println(arr2(1))

    //    arr1(1) = 1
    //    println(arr1(1))

    println("-------TODO 3、添加元素-------------------------")

    val newArr1 = arr1 :+ 15
    println(arr1)
    println(newArr1)
    println(newArr1 == arr1)

    // +=相当于追加了
    val newArr2 = arr1 += 19
    println(arr1)
    println(newArr2)
    println(newArr2 == arr1)
    newArr2 += 13
    println(arr1)

    //往前追加 +:
    77 +=: arr1
    println(arr1)
    println(newArr2)

    arr1.append(36)
    arr1.prepend(11, 34)
    arr1.insert(1, 35, 59)
    println(arr1)

    arr1.insertAll(2, newArr1)
    arr1.prependAll(newArr2)

    println(arr1)
    println("-------TODO 4、删除元素-------------------")
    arr1.remove(3)
    println(arr1)

    arr1.remove(0, 10)
    println(arr1)

    //寻找删除、找不到什么都不做
    arr1 -= 13
    println(arr1)

    println("-------TODO 5、可变数组转不可变数组-------------------")
    val arr: ArrayBuffer[Int] = ArrayBuffer(23, 56, 46)
    val newArray: Array[Int] = arr.toArray
    println(newArray.mkString(","))
    println(arr)

    println("-------------不可变数组转换为可变数组---------------")
    val buffer: mutable.Buffer[Int] = newArray.toBuffer
    println(buffer)
    println(newArray)
  }

}

3、不可变数组与可变数组的转换

1)说明

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

2)案例实操

package chapter07

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

/**
 * 数组、可变数组
 *
 */
object Test02_ArrayBuffer {
  def main(args: Array[String]): Unit = {
    //TODO 1、创建可变数组
    println("--------TODO 1、创建可变数组-----------------")
    val arr1: ArrayBuffer[Int] = new ArrayBuffer[Int]()
    val arr2 = ArrayBuffer(23, 44, 66, 77, 31)

    println(arr1)
    println(arr1.mkString(","))
    println(arr2)

    println("--------TODO 2、访问元素-----------------")
    //TODO 2、访问元素
    println(arr2(1))
    arr2(1) = 39
    println(arr2(1))

    //    arr1(1) = 1
    //    println(arr1(1))

    println("-------TODO 3、添加元素-------------------------")

    val newArr1 = arr1 :+ 15
    println(arr1)
    println(newArr1)
    println(newArr1 == arr1)

    // +=相当于追加了
    val newArr2 = arr1 += 19
    println(arr1)
    println(newArr2)
    println(newArr2 == arr1)
    newArr2 += 13
    println(arr1)

    //往前追加 +:
    77 +=: arr1
    println(arr1)
    println(newArr2)

    arr1.append(36)
    arr1.prepend(11, 34)
    arr1.insert(1, 35, 59)
    println(arr1)

    arr1.insertAll(2, newArr1)
    arr1.prependAll(newArr2)

    println(arr1)
    println("-------TODO 4、删除元素-------------------")
    arr1.remove(3)
    println(arr1)

    arr1.remove(0, 10)
    println(arr1)

    //寻找删除、找不到什么都不做
    arr1 -= 13
    println(arr1)

    println("-------TODO 5、可变数组转不可变数组-------------------")
    val arr: ArrayBuffer[Int] = ArrayBuffer(23, 56, 46)
    val newArray: Array[Int] = arr.toArray
    println(newArray.mkString(","))
    println(arr)

    println("-------------不可变数组转换为可变数组---------------")
    val buffer: mutable.Buffer[Int] = newArray.toBuffer
    println(buffer)
    println(newArray)
  }

}

4、多维数组

1)多维数组定义

val arr = Array.ofDimDouble
说明:二维数组中有三个一维数组,每个一维数组中有四个元素

2)案例实操

package chapter07

/**
 * 多维数组
 */
object Test03_MulArray {
  def main(args: Array[String]): Unit = {
    //1、创建多维数组
    val array: Array[Array[Int]] = Array.ofDim[Int](2, 3)

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

    println(array.mkString(","))

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


    println("-------循环二----------------")

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

    println("-------简写----------------")
    array.foreach(line => line.foreach(println))

    //简写 _代替
    println("-------_代替简写----------------")
    array.foreach(_.foreach(println))

  }
}

三、列表 List

1、不可变 List

1)说明

(1)List 默认为不可变集合
(2)创建一个 List(数据有顺序,可重复)
(3)遍历 List
(4)List 增加数据
(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化
(6)取指定数据
(7)空集合 Nil

2)案例实操

package chapter07

/**
 * 1)说明
 * (1)List 默认为不可变集合
 * (2)创建一个 List(数据有顺序,可重复)
 * (3)遍历 List
 * (4)List 增加数据
 * (5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化
 * (6)取指定数据
 * (7)空集合 Nil
 */
object Test04_List {
  def main(args: Array[String]): Unit = {
    //1、创建
    var list = List(23, 45, 78)
    println(list)

    //2、索引赋值不行
    //list(1) = 20

    //3、访问遍历、foreach 的循环
    list.foreach(e => {
      println(e)
    })

    //4、添加元素、 前+ 对应前、后+ 对应后
    val list1 = 10 +: list
    val list2 = list :+ (24)

    println(list1)
    println(list2)

    println("----------5、 .:: 往前添加-----------------")
    val list4 = list2.::(51)
    println(list4)

    println("----------6、 Nil.:: 相当于创建新的数组-----------------")
    val list5 = Nil.::(51)
    println(list5)

    println("----------7、扩展 添加元素另外一种创建新列表的方式 -----------------")
    val list6 = 32 :: Nil
    val list7 = 17 :: 28 :: 59 :: 16 :: Nil

    println(list6)
    println(list7)

    println("----------8、合并列表 -----------------")

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

2、可变 ListBuffer

1)说明

(1)创建一个可变集合 ListBuffer
(2)向集合中添加数据
(3)打印集合数据

2)案例实操

package chapter07

import scala.collection.mutable.ListBuffer

/**
 * Scala集合
 * 列表
 * 可变列表
 */
object Test05_ListBuffer {
  def main(args: Array[String]): Unit = {
    //1、创建可变列表
    val list1: ListBuffer[Int] = new ListBuffer[Int]();
    val list2 = ListBuffer(12, 45, 23, 12)

    println(list1)
    println(list2)

    println("-------------添加元素------------------")
    //2、添加元素
    list1.append(13, 56)
    list2.prepend(20)

    //指定索引新增
    list1.insert(1, 19, 22)

    println(list1)
    println(list2)

    println("----------前面加连个-----后面加两个----------------")
    31 +=: 96 +=: list1 += 25 += 11
    println(list1)

    println("-------3、合并元素---------------")
    //3、合并元素
    val list3 = list1 ++ list2
    println(list3)

    // ↓ 简写
    println("-------简写---------------")
    list1 ++= list2
    println(list1)
    println(list2)

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

    println("-------5、删除元素---------------")

    list2.remove(2)
    list2 -= 23
    println(list2)

  }

}

四、Set 集合

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

1、不可变 Set

1)说明

(1)Set 默认是不可变集合,数据无序
(2)数据不可重复
(3)遍历集合

2)案例实操

package chapter07

/**
 * Set集合
 * 不可变set
 *
 * 对于原始的set里面的内容不做改变的、而得到的结果是一个新的set集合 对象
 *
 * 可变的、直接基于原始的做改变
 */
object Test06_ImmutableSet {
  def main(args: Array[String]): Unit = {

    //1、创建Set 重复的自动去除
    val set1 = Set(12, 23, 34, 56, 12, 23, 12)
    println(set1)


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


    //3、合并元素
    println("---------3、合并元素------------")
    val set3 = Set(19, 13, 23, 53, 67, 99)

    val set4 = set2 ++ set3
    println(set2)
    println(set3)
    println(set4)


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

2、 可变 mutable.Set

1)说明

(1)创建可变集合 mutable.Set
(2)打印集合
(3)集合添加元素
(4)向集合中添加元素,返回一个新的 Set
(5)删除数据

2)案例实操

package chapter07

import scala.collection.mutable

/**
 * Set集合
 * 可变Set
 *
 * 不可变的集合类型推荐 :符号的方法
 * 可变的集合推荐使用英文名称
 */
object Test07_MutableSet {
  def main(args: Array[String]): Unit = {
    val set1: mutable.Set[Int] = mutable.Set(12, 23, 53, 11, 13, 12, 78)
    println(set1)

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

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

    set1 += 11
    println(set1)

    //可以判断元素是否添加成功
    val bool = set1.add(10)
    println(bool)
    println(set1)

    //判断已存在、不在添加
    val bool1 = set1.add(10)
    println(bool1)
    println(set1)

    println("=======删除元素================")

    set1 -= 11
    println(set1)

    val boo2 = set1.remove(10)
    println(boo2)
    println(set1)

    val bool3 = set1.add(10)
    println(bool3)
    println(set1)

    println("=======合并连个Set================")

    val set3 = mutable.Set(13, 12, 13, 27, 98, 29)

    val set4= set1 ++ set3

    //++= 这个符号谁调用谁改变

    set1 ++= set3
    println(set1)
    println(set3)
    println(set4)

  }
}

五、Map 集合

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

1、不可变 Map

1)说明

(1)创建不可变集合 Map
(2)循环打印
(3)访问数据
(4)如果 key 不存在,返回 0

2)案例实操

package chapter07

/**
 * Scala 集合
 * Map集合不可变
 */
object Test08_ImmutableMap {
  def main(args: Array[String]): Unit = {

    //1、创建Map
    val map1: Map[String, Int] = Map("a" -> 13, "b" -> 24, "hello" -> 80)
    println(map1)
    println(map1.getClass)

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

    //3、取Map中的集合所有Key 或者value
    println("-----------3、取Map中的集合所有Key 或者value------------")
    for (key <- map1.keys) {
      println(s"$key --->${map1.get(key)}")
    }

    //4、访问某一个key的value
    println("a :" + map1.get("a").get)
    println("c :" + map1.get("c"))
    println("c :" + map1.getOrElse("c", 0))

  }
}

2、可变 Map

1)说明

(1)创建可变集合
(2)打印集合
(3)向集合增加数据
(4)删除数据
(5)修改数据

2)案例实操

package chapter07

import scala.collection.mutable

/**
 * Map集合
 * 可变Map
 */
object Test09_MutableMap {
  def main(args: Array[String]): Unit = {
    //1、创建Map
    val map1: mutable.Map[String, Int] = mutable.Map("a" -> 13, "b" -> 53, "hello" -> 23)
    println(map1)
    println(map1.getClass)

    println("=============================")
    //2、添加元素
    map1.put("c", 5)
    map1.put("d", 6)
    println(map1)

    map1 += (("e", 7))
    println(map1)

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

    //3、删除元素
    println(map1("c"))
    map1.remove("c")
    println(map1)
    println(map1.getOrElse("c", 0))


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

    map1 += (("e", 7))
    println(map1)


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

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

六、元组

1)说明

元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。
注意:元组中最大只能有 22 个元素。

2)案例实操

(1)声明元组的方式:(元素 1,元素 2,元素 3)
(2)访问元组
(3)Map 中的键值对其实就是元组,只不过元组的元素个数为 2,称之为对偶

package chapter07

/**
 * Scala 集合
 * 元组
 *
 */
object Test10_Tuple {
  def main(args: Array[String]): Unit = {
    //1、创建元组
    val tuple: (String, Int, Char, Boolean) = ("hello", 100, 'a', true)

    println(tuple)

    //2、访问数据
    println(tuple._1)
    println(tuple._2)
    println(tuple._3)
    println(tuple._4)

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

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

七、集合常用函数

1、基本属性和常用操作

1)说明

(1)获取集合长度
(2)获取集合大小
(3)循环遍历
(4)迭代器
(5)生成字符串
(6)是否包含

2)案例实操

package chapter07


/**
 *
 *  通用的属性和方法
 * 线性序列都可以获取长度
 */
object Test11_CommonOp {
  def main(args: Array[String]): Unit = {
    var list = List(1, 3, 5, 7, 89)

    var set = Set(23, 13, 45, 68)

    //1、获取集合长度
    println(list.length)
    //2、获取集合大小
    println(set.size)

    //3、循环遍历
    println("list...")
    for (elem <- list) {
      println(elem)
    }


    println("set...")
    set.foreach(println)

    //4、迭代器

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

    //6、是否包含

    println(list.contains(23))
    println(set.contains(23 ))
  }
}

2、衍生集合

1)说明

(1)获取集合的头
(2)获取集合的尾(不是头的就是尾)
(3)集合最后一个数据
(4)集合初始数据(不包含最后一个)
(5)反转
(6)取前(后)n 个元素
(7)去掉前(后)n 个元素
(8)并集
(9)交集
(10)差集
(11)拉链
(12)滑窗

2)案例实操

package chapter07

/**
 * 衍生集合
 */
object Test12_DerivedCollection {
  def main(args: Array[String]): Unit = {

    val list1 = List(1, 3, 5, 7, 289)
    val list2 = List(3, 7, 2, 45, 4, 8, 19)
    //(1)获取集合的头

    println(list1.head)

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

    //(3)集合最后一个数据
    println(list2.last)

    //(4)集合初始数据(不包含最后一个)
    println(list2.init)
    //(5)反转
    println(list2.reverse)

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

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

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

    println(list1 ::: list2)

    //如果是set做并集,会去重
    println("如果是set做并集,会去重")
    val set1 = Set(1, 3, 5, 7, 289)
    val set2 = Set(3, 7, 2, 45, 4, 8, 19)
    println(set1.union(set2))
    println(set1 ++ set2)

    //(9)交集
    println("交集")
    val intersect = list1.intersect(list2)
    println("intersect: " + intersect)

    //(10)差集
    val diff1 = list1.diff(list2)
    val diff2 = list2.diff(list1)
    println("diff1 " + diff1)
    println("diff2 " + diff2)

    //(11)拉链
    println("拉链")
    println("zip: " + list1.zip(list2))
    println("zip: " + list2.zip(list1))

    //(12)滑窗
    println("滑窗")
    for (elem <- list1.sliding(3)) {
      println(elem)
    }
    
    println("滑窗 每个两个滑动一次")
    for (elem <- list1.sliding(3,2)) {
      println(elem)
    }

  }
}

3、集合计算简单函数

1)说明

(1)求和
(2)求乘积
(3)最大值
(4)最小值
(5)排序

2)实操

package chapter07

/**
 * 集合常用函数
 * 简单计算函数
 */
object Test13_SimpleFunction {
  def main(args: Array[String]): Unit = {
    val list = List(1, 2, 4, 8, 5, -3)

    val list2 = List(("a", 5), ("b", 1), ("c", 8), ("d", 2), ("e", -3), ("f", 4))

    //1、求和
    var sum = 0
    for (elem <- list) {
      sum += elem
    }
    println(sum)
    println(list.sum)

    //2、求乘积

    println(list.product)

    //3、最大值
    println(list.max)

    println(list2.maxBy((tuple: (String, Int)) => tuple._2))
    //拿第二个元素
    println(list2.maxBy(_._2))

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

    //5、排序
    println("排序")
    // 5.1 sorted
    val sortedList = list.sorted
    println(sortedList)

    println("从大到小逆序排序")
    println(list.sorted.reverse)

    //传入隐式参数
    println(list.sorted(Ordering[Int].reverse))
    println(list2.sorted)

    //5.2 sortBy  //Ordering[Int].reverse 反过来的
    println(list2.sortBy(_._2))
    println(list2.sortBy(_._2)(Ordering[Int].reverse))

    //5.3 sortWith //从小到大排列
    println(list.sortWith((a: Int, b: Int) => {
      a < b
    }))

    //小于排序
    println(list.sortWith(_ < _))

    //大于排序
    println(list.sortWith(_ > _))


  }
}

(1)sorted
对一个集合进行自然排序,通过传递隐式的 Ordering
(2)sortBy
对一个属性或多个属性进行排序,通过它的类型。
(3)sortWith
基于函数的排序,通过一个 comparator 函数,实现自定义排序的逻辑。

4、集合计算高级函数

1)说明

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

(2)转化/映射(map)
将集合中的每一个元素映射到某一个函数

(3)扁平化

(4)扁平化+映射 注:flatMap 相当于先进行 map 操作,在进行 flatten 操作
集合中的每个元素的子元素映射到某个函数并返回新集合

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

(6)简化(归约)

(7)折叠

2)实操

package chapter07

/**
 * 集合计算高级函数
 */
object Test14_HighLevelFunction_Map {
  def main(args: Array[String]): Unit = {
    var 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))


    //2、map
    //把集合中每个数乘以2
    println("---------------------------")
    println(list.map(_ * 2))
    println(list.map(x => x * x))


    //3、扁平化
    println("扁平化")
    val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
    val ints = nestedList(0) ::: nestedList(1) ::: nestedList(2)
    println(ints)

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


    //4、扁平映射
    println("扁平映射")
    //将一组字符串进行分词,并保存成单词的列表
    val strings: List[String] = List("hello word", "hello scala", "hello java", "we study")
    val stringses: List[Array[String]] = strings.map(_.split(" ")) //分词
    val flattenList = stringses.flatten
    println(flattenList)


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

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


    //6、给定一组词汇,按照单词的首字母进行分组
    val strings2 = List("china", "america", "alice", "canada", "cary", "bob", "japan")
    println(strings2.groupBy(_.charAt(0)))
  }
}

3)Reduce 方法和Fold 方法

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

package chapter07

/**
 * 高级计算函数
 * 集合转换操作Reduce
 */
object Test15_HighLevelFunction_Reduce {
  def main(args: Array[String]): Unit = {
    val list = List(1, 2, 3, 4)

    //1、Reduce
    println(list.reduce(_ + _))
    println(list.reduceLeft(_ + _))
    println(list.reduceRight(_ + _))

    println("------------------------------------")


    //reduce 可以认为初始值就是第一个数
    val list2 = List(3, 4, 5, 8, 10)
    println(list2.reduce(_ - _)) //-24
    println(list2.reduceLeft(_ - _))
    println(list2.reduceRight(_ - _))

    //2、fold 需要单独传入一个初始值
    println("fold............")
    println(list.fold(10)(_ + _)) //10+1+2+3+4
    println(list.foldLeft(10)(_ - _)) // 10 - 1 - 2 - 3 - 4
    println(list.foldRight(11)(_ - _)) //3-(4-(5-(8-(10-11))))
  }
}

4)案例实操:两个集合合并

package chapter07

import scala.collection.mutable

/**
 * 合并MAp
 */
object Test16_MergeMap {
  def main(args: Array[String]): Unit = {

    val map = Map("a" -> 1, "b" -> 3, "c" -> 6)
    val map2 = mutable.Map("a" -> 6, "b" -> 2, "c" -> 9, "d" -> 3)

    //初始map2
    val map3: mutable.Map[String, Int] = map.foldLeft(map2)(
      //更新里面的值
      (mergedMap, kv) => {
      val key = kv._1
      val value = kv._2
      //mergedMap.getOrElse 取当前的值 +value
      mergedMap(key) = mergedMap.getOrElse(key, 0) + value
      mergedMap
    })

    println(map3)

  }
}

八、普通 WordCount 案例

1)需求

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

2)需求分析

大数据之Scala 集合 完整使用(第七章)

3)案例实操

package chapter07

/**
 * 普通的WordCount
 */
object Test17_CommonWordCount {

  def main(args: Array[String]): Unit = {

    val strings: List[String] = List(
      "hello",
      "hello word",
      "hello scala",
      "hello spark form scala",
      "hello flink from scala"
    )

    //1、对字符传进行切分、得到一个打散所有单词的列表
    val wordList1: List[Array[String]] = strings.map(_.split(" "))
    val wordList2: List[String] = wordList1.flatten
    println(wordList2)

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

    //3、对分组之后的LIST取长度、得到每个单词个数
    val countMap: Map[String, Int] = groupMap.map(kv => (kv._1, kv._2.length))
    println("....countMap: " + countMap)

    //4、将Map转换为list、并排序取前三
    val sortList: List[(String, Int)] = countMap.toList

      //第一个取 _._2 意思取第二个元素COUNT值、做一个降序的排列
      .sortWith(_._2 > _._2)
    println(sortList)

  }

}

九、复杂 WordCount 案例

1)方式一

package chapter07

import scala.math.Ordering

object Test18_ComplexWordCount {
  def main(args: Array[String]): Unit = {
    val tupleList: List[(String, Int)] = List(
      ("hello", 1),
      ("hello word", 2),
      ("hello scala", 3),
      ("hello spark form scala", 1),
      ("hello flink from scala", 2))

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


    //2、接下来的操作和普通版本完全一致
    val tuples: List[(String, Int)] = newStringList.flatMap(
      _.split(" "))
      .groupBy(e => e)
      .map(kv => (
        kv._1, kv._2.size
      ))
      .toList
      .sortBy(_._2)(Ordering[Int].reverse)
      .take(3)

    println(tuples)



    //思路二、直接基于预统计的结果进行转换
    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(tuple => tuple._1)
    println(preCountMap)


    //3、叠加每个单词预统计的个数值
    val countMap: Map[String, Int] = preCountMap.mapValues(
      tupleList => tupleList.map(_._2).sum
    )
    println("............"+countMap)

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


}

十、 队列

1)说明

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

2)案例实操

package chapter07

import scala.collection.immutable.Queue
import scala.collection.mutable

/**
 * 队列_Queue
 */
object Test19_Queue {
  def main(args: Array[String]): Unit = {
    val queue: mutable.Queue[String] = new mutable.Queue[String]()

    //1、创建一个可变队列
    queue.enqueue("a", "b", "c")
    println(queue)
    println(queue.dequeue())

    println(queue)
    println(queue.dequeue())

    println(queue)
    println(queue.dequeue())

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

十一、并行集合

1)说明

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

2)案例实操

package chapter07

import scala.collection.immutable

/**
 * 并行集合
 */
object Test20_Parallel {
  def main(args: Array[String]): Unit = {
    //串行
    val strings: immutable.IndexedSeq[Long] = (1 to 100).map(
      x => Thread.currentThread().getId
    )
    println(strings)

    //并行
    val result2 = (1 to 100).par.map(
      x => Thread.currentThread().getId
    )
    println(result2)
  }
}

上一篇:DeepFacelab更新:分辨率提至640,效率翻倍!


下一篇:jsonobject