大数据Scala学习之旅第二篇

424 阅读4分钟

「这是我参与11月更文挑战的第30天,活动详情查看:2021最后一次更文挑战」。

一、集合

1、集合简介

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

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

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

    • 可变集合: scala.collection.mutable

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

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

1.1、不可变集合继承图

image.png

  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 的区别:

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

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

1.2、可变集合继承图

image.png

2、数组

2.1、不可变数组

  1. 第一种方式定义数组

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

    • new 是关键字
    • [Int]是指定可以存放的数据类型,如果希望存放任意数据类型,则指定 Any
    • (10),表示数组的大小,确定后就不可以变化
  2. 案例实操

    object TestArray{
     def main(args: Array[String]): Unit = {
     //(1)数组定义
     val arr01 = new Array[Int](4)
     println(arr01.length) // 4
     //(2)数组赋值
     //(2.1)修改某个元素的值
     arr01(3) = 10
     //(2.2)采用方法的形式给数组赋值
     arr01.update(0,1)
     //(3)遍历数组
     //(3.1)查看数组
     println(arr01.mkString(","))
     //(3.2)普通遍历
     for (i <- arr01) {
     println(i)
     }
     //(3.3)简化遍历
     def printx(elem:Int): Unit = {
     println(elem)
     }
     arr01.foreach(printx)
     // arr01.foreach((x)=>{println(x)})
     // arr01.foreach(println(_))
     arr01.foreach(println)
     //(4)增加元素(由于创建的是不可变数组,增加元素,其实是产生新的数组)
     println(arr01)
     val ints: Array[Int] = arr01 :+ 5
     println(ints)
     } }
    
  3. 第二种方式定义数组

    val arr1 = Array(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.2、可变数组

  1. 定义变长数组

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

    • [Any]存放任意数据类型
    • (3, 2, 5)初始化好的三个元素
    • ArrayBuffer 需要引入 scala.collection.mutable.ArrayBuffer
  2. 案例实操

    • ArrayBuffer 是有序的集合

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

      import scala.collection.mutable.ArrayBuffer
      object TestArrayBuffer {
       def main(args: Array[String]): Unit = {
       //(1)创建并初始赋值可变数组
       val arr01 = ArrayBuffer[Any](1, 2, 3)
       //(2)遍历数组
       for (i <- arr01) {
       println(i)
       }
       println(arr01.length) // 3
       println("arr01.hash=" + arr01.hashCode())
       //(3)增加元素
       //(3.1)追加数据
       arr01.+=(4)
       //(3.2)向数组最后追加数据
       arr01.append(5,6)
       //(3.3)向指定的位置插入数据
       arr01.insert(0,7,8)
       println("arr01.hash=" + arr01.hashCode())
       //(4)修改元素
       arr01(1) = 9 //修改第 2 个元素的值
       println("--------------------------")
       for (i <- arr01) {
       println(i)
       }
       println(arr01.length) // 5
       } }
      

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

  1. 说明

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

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

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

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

  2. 案例实操

    object TestArrayBuffer {
     def main(args: Array[String]): Unit = {
     //(1)创建一个空的可变数组
     val arr2 = ArrayBuffer[Int]()
     //(2)追加值
     arr2.append(1, 2, 3)
     println(arr2) // 1,2,3
     //(3)ArrayBuffer ==> Array
     //(3.1)arr2.toArray 返回的结果是一个新的定长数组集合
     //(3.2)arr2 它没有变化
     val newArr = arr2.toArray
     println(newArr)
    
     //(4)Array ===> ArrayBuffer
     //(4.1)newArr.toBuffer 返回一个变长数组 newArr2
     //(4.2)newArr 没有任何变化,依然是定长数组
     val newArr2 = newArr.toBuffer
     newArr2.append(123)
     println(newArr2)
     }
    }
    

2.4、多维数组

  1. 多维数组定义

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

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

  2. 案例实操

    object DimArray {
     def main(args: Array[String]): Unit = {
    
     //(1)创建了一个二维数组, 有三个元素,每个元素是,含有 4 个元素一维数组()
     val arr = Array.ofDim[Int](3, 4)
     arr(1)(2) = 88
     //(2)遍历二维数组
     for (i <- arr) { //i 就是一维数组
     for (j <- i) {
     print(j + " ")
     }
     println()
     }
     } }
    

3、列表 List

3.1、不可变 List

  1. 说明

    • List 默认为不可变集合
    • 创建一个 List(数据有顺序,可重复)
    • 遍历 List
    • List 增加数据
    • 集合间合并:将一个整体拆成一个一个的个体,称为扁平化
    • 取指定数据
    • 空集合 Nil
  2. 案例实操

    object TestList {
     def main(args: Array[String]): Unit = {
     //(1)List 默认为不可变集合
     //(2)创建一个 List(数据有顺序,可重复)
     val list: List[Int] = List(1,2,3,4,3)
    
     //(7)空集合 Nil
     val list5 = 1::2::3::4::Nil
     //(4)List 增加数据
     //(4.1)::的运算规则从右向左
     //val list1 = 5::list
     val list1 = 7::6::5::list
     //(4.2)添加到第一个元素位置
     val list2 = list.+:(5)
     //(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化
     val list3 = List(8,9)
     //val list4 = list3::list1
     val list4 = list3:::list1
     //(6)取指定数据
     println(list(0))
     //(3)遍历 List
     //list.foreach(println)
     //list1.foreach(println)
     //list3.foreach(println)
     //list4.foreach(println)
     list5.foreach(println)
     } }
    

3.2、可变 ListBuffer

  1. 说明

    • 创建一个可变集合 ListBuffer
    • 向集合中添加数据
    • 打印集合数据
  2. 案例实操

    import scala.collection.mutable.ListBuffer
    object TestList {
     def main(args: Array[String]): Unit = {
     //(1)创建一个可变集合
     val buffer = ListBuffer(1,2,3,4)
     //(2)向集合中添加数据
     buffer.+=(5)
    buffer.append(6)
    buffer.insert(1,2)
     //(3)打印集合数据
     buffer.foreach(println)
    //(4)修改数据
    buffer(1) = 6
    buffer.update(1,7)
    //(5)删除数据
    buffer.-(5)
    buffer.-=(5)
    buffer.remove(5)
     } }
    

4、Set 集合

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

4.1、不可变 Set

  1. 说明

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

    • 数据不可重复

    • 遍历集合

  2. 案例实操

    object TestSet {
     def main(args: Array[String]): Unit = {
     //(1)Set 默认是不可变集合,数据无序
     val set = Set(1,2,3,4,5,6)
     //(2)数据不可重复
     val set1 = Set(1,2,3,4,5,6,3)
     //(3)遍历集合
     for(x<-set1){
     println(x)
     }
     } }
    

4.2、可变 mutable.Set

  1. 说明

    • 创建可变集合 mutable.Set
    • 打印集合
    • 集合添加元素
    • 向集合中添加元素,返回一个新的 Set
    • 删除数据
  2. 案例实操

    object TestSet {
     def main(args: Array[String]): Unit = {
     //(1)创建可变集合
     val set = mutable.Set(1,2,3,4,5,6)
     //(3)集合添加元素
     set += 8
     //(4)向集合中添加元素,返回一个新的 Set
     val ints = set.+(9)
     println(ints)
     println("set2=" + set)
     //(5)删除数据
     set-=(5)
     //(2)打印集合
     set.foreach(println)
     println(set.mkString(","))
     } }
    
    

5、Map 集合

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

5.1、不可变 Map

  1. 说明

    • 创建不可变集合 Map
    • 循环打印
    • 访问数据
    • 如果 key 不存在,返回 0
  2. 案例实操

    object TestMap {
     def main(args: Array[String]): Unit = {
     // Map
     //(1)创建不可变集合 Map
     val map = Map( "a"->1, "b"->2, "c"->3 )
     //(3)访问数据
     for (elem <- map.keys) {
     // 使用 get 访问 map 集合的数据,会返回特殊类型 Option(选项):
    有值(Some),无值(None)
     println(elem + "=" + map.get(elem).get)
     }
     //(4)如果 key 不存在,返回 0
     println(map.get("d").getOrElse(0))
     println(map.getOrElse("d", 0))
     //(2)循环打印
     map.foreach((kv)=>{println(kv)})
     } }
    

5.2、可变 Map

  1. 说明

    • 创建可变集合
    • 打印集合
    • 向集合增加数据
    • 删除数据
    • 修改数据
  2. 案例实操

    object TestSet {
     def main(args: Array[String]): Unit = {
     //(1)创建可变集合
     val map = mutable.Map( "a"->1, "b"->2, "c"->3 )
     //(3)向集合增加数据
     map.+=("d"->4)
     // 将数值 4 添加到集合,并把集合中原值 1 返回
     val maybeInt: Option[Int] = map.put("a", 4)
     println(maybeInt.getOrElse(0))
     //(4)删除数据
     map.-=("b", "c")
     //(5)修改数据
     map.update("d",5)
    map("d") = 5
     //(2)打印集合
     map.foreach((kv)=>{println(kv)})
     } }
    

6、元组

  1. 说明

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

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

  2. 案例实操

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

    • 访问元组

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

      object TestTuple {
       def main(args: Array[String]): Unit = {
       //(1)声明元组的方式:(元素 1,元素 2,元素 3)
       val tuple: (Int, String, Boolean) = (40,"bobo",true)
       //(2)访问元组
       //(2.1)通过元素的顺序进行访问,调用方式:_顺序号
       println(tuple._1)
       println(tuple._2)
       println(tuple._3)
       //(2.2)通过索引访问数据
       println(tuple.productElement(0))
       //(2.3)通过迭代器访问数据
       for (elem <- tuple.productIterator) {
       println(elem)
       }
       //(3)Map 中的键值对其实就是元组,只不过元组的元素个数为 2,称之为
      对偶
       val map = Map("a"->1, "b"->2, "c"->3)
       val map1 = Map(("a",1), ("b",2), ("c",3))
       map.foreach(tuple=>{println(tuple._1 + "=" + tuple._2)})
       } }
      

二、友情链接

大数据Scala学习之旅第一篇