Scala笔记3

Scala第十章节

章节目标

  1. 掌握数组, 元组相关知识点
  2. 掌握列表, 集, 映射相关知识点
  3. 了解迭代器的用法
  4. 掌握函数式编程相关知识点
  5. 掌握学生成绩单案例

1. 数组

1.1 概述

数组就是用来存储多个同类型元素的容器, 每个元素都有编号(也叫: 下标, 脚标, 索引), 且编号都是从0开始数的. Scala中, 有两种数组,一种是定长数组,另一种是变长数组.

1.2 定长数组
1.2.1 特点
  1. 数组的长度不允许改变.
  2. 数组的内容是可变的.
1.2.2 语法
  • 格式一: 通过指定长度定义数组
 val/var 变量名 = new Array[元素类型](数组长度)
  • 格式二: 通过指定元素定义数组
  val/var 变量名 = Array(元素1, 元素2, 元素3...)

注意:

  1. 在scala中,数组的泛型使用 [] 来指定.
  2. 使用 数组名(索引) 来获取数组中的元素.
  3. 数组元素是有默认值的, Int:0, Double:0.0, String: null
  4. 通过 数组名.length 或者 数组名.size 来获取数组的长度.
1.2.3 示例

需求

  1. 定义一个长度为10的整型数组, 设置第1个元素为11, 并打印第1个元素.
  2. 定义一个包含"java", “scala”, "python"这三个元素的数组, 并打印数组长度.
    参考代码
//案例: 演示定长数组 
object ClassDemo01 {
   
	def main(args: Array[String]): Unit = {
   
		//1. 定义一个长度为10的整型数组, 设置第1个元素为11, 并打印第1个元素. val arr1 = new Array[Int](10)
		arr1(0) = 11
		println(arr1(0)) //打印数组的第1个元素.
		println("-" * 15) //分割线
		//2. 定义一个包含"java", "scala", "python"这三个元素的数组, 并打印数组长度. val arr2 = Array("java", "scala", "python")
		println(arr2.length) //打印数组的长度
	}
}
1.3 变长数组
1.3.1 特点
  • 数组的长度和内容都是可变的,可以往数组中添加、删除元素.
1.3.2 语法
  • 创建变长数组,需要先导入ArrayBuffer类.
   	import scala.collection.mutable.ArrayBuffer
  • 定义格式一: 创建空的ArrayBuffer变长数组
   	 val/var 变量名 = ArrayBuffer[元素类型]()
  • 定义格式二: 创建带有初始元素的ArrayBuffer变长数组
   	 val/var 变量名 = ArrayBuffer(元素1,元素2,元素3....)
1.3.3 示例一: 定义变长数组
  1. 定义一个长度为0的整型变长数组.
  2. 定义一个包含"hadoop", “storm”, "spark"这三个元素的变长数组.
  3. 打印结果.

参考代码

//1. 导包.
import scala.collection.mutable.ArrayBuffer
//案例: 演示变长数组 
object ClassDemo02 {
   
   def main(args: Array[String]): Unit = {
   
   	 //2. 定义一个长度为0的整型变长数组.
   	val arr1 = new ArrayBuffer[Int]() 
   	println("arr1:" + arr1)
   	//3. 定义一个包含"hadoop", "storm", "spark"这三个元素的变长数组. 
   	val arr2 = ArrayBuffer("hadoop", "storm", "spark")
   	println("arr2:" + arr2)
   }
}

1.3.4 示例二: 增删改元素

针对Scala中的变长数组, 可通过下述方式来修改数组中的内容.

格式

  • 使用 += 添加单个元素
  • 使用 -= 删除单个元素
  • 使用 ++= 追加一个数组到变长数组中
  • 使用 --= 移除变长数组中的指定多个元素

示例

  1. 定义一个变长数组,包含以下元素: “hadoop”, “spark”, “flink”
  2. 往该变长数组中添加一个"flume"元素
  3. 从该变长数组中删除"hadoop"元素
  4. 将一个包含"hive", "sqoop"元素的数组, 追加到变长数组中.
  5. 从该变长数组中删除"sqoop", "spark"这两个元素.
  6. 打印数组, 查看结果.

参考代码

//导包
import scala.collection.mutable.ArrayBuffer
//案例: 修改变长数组中的内容. 
object ClassDemo03 {
   
	def main(args: Array[String]): Unit = {
   
		//1. 定义一个变长数组,包含以下元素: "hadoop", "spark", "flink" 
		val arr = ArrayBuffer("hadoop", "spark", "flink")
		//2. 往该变长数组中添加一个"flume"元素
		arr += "flume"
		//3. 从该变长数组中删除"hadoop"元素
		arr -= "hadoop"
		//4. 将一个包含"hive", "sqoop"元素的数组, 追加到变长数组中.
		arr ++= Array("hive", "sqoop")
		//5. 从该变长数组中删除"sqoop", "spark"这两个元素.
		arr --= Array("sqoop", "spark")
		//6. 打印数组, 查看结果.
	    println(s"arr: ${
     arr}")
 	 }
}
1.4 遍历数组

概述
在Scala中, 可以使用以下两种方式来遍历数组:

  1. 使用 索引 遍历数组中的元素
  2. 使用 for表达式 直接遍历数组中的元素

示例

  1. 定义一个数组,包含以下元素1,2,3,4,5
  2. 通过两种遍历方式遍历数组,并打印数组中的元素

参考代码

//案例: 遍历数组 
object ClassDemo04 {
   
	def main(args: Array[String]): Unit = {
   
		//1. 定义一个数组,包含以下元素1,2,3,4,5
		val arr = Array(1, 2, 3, 4, 5)
		//2. 通过两种遍历方式遍历数组,并打印数组中的元素. 
		//方式一: 遍历索引的形式实现.
		for(i <- 0 to arr.length -1) 
		println(arr(i)) 	
		println("-" * 15) //分割线
		for(i <- 0 until arr.length) println(arr(i)) 
		println("-" * 15) //分割线
		//方式二: 直接遍历数组元素.
	    for(i <- arr) println(i)
  }
}
注意:
0 until n 获取0~n之间的所有整数, 包含0, 不包含n. 
0 to n 获取0~n之间的所有整数, 包含0, 也包含n.
1.5 数组常用算法

概述
Scala中的数组封装了一些常用的计算操作,将来在对数据处理的时候,不需要我们自己再重新实现, 而是可以直接 拿来用。以下为常用的几个算法:

  • sum()方法: 求和
  • max()方法: 求最大值
  • min()方法: 求最小值
  • sorted()方法: 排序, 返回一个新的数组.
  • reverse()方法: 反转, 返回一个新的数组.

需求

  1. 定义一个数组, 包含4, 1, 6, 5, 2, 3这些元素.
  2. 在main方法中, 测试上述的常用算法.

参考代码

 //案例: 数组的常用算法 
 object ClassDemo05 {
   
	def main(args: Array[String]): Unit = {
   
		//1. 定义一个数组, 包含4, 1, 6, 5, 2, 3这些元素.
		val arr = Array(4, 1, 6, 5, 2, 3)
		//2. 在main方法中, 测试上述的常用算法.
		//测试sum
		println(s"sum: ${
     arr.sum}")
		//测试max
		println(s"max: ${
     arr.max}")
		//测试min
		println(s"min: ${
     arr.min}")
		//测试sorted
		val arr2 = arr.sorted
		//测试reverse
		val arr3 = arr.sorted.reverse 
		//即: arr3的内容为: 6, 5, 4, 3, 2, 1 
		//3. 打印数组.
		for(i <- arr) println(i)
		println("-" * 15)
		for(i <- arr2) println(i)
		println("-" * 15)
		for(i <- arr3) println(i)
	} 
}
 

2. 元组

元组一般用来存储多个不同类型的值。例如同时存储姓名,年龄,性别,出生年月这些数据, 就要用到元组来存储
了。并且元组的长度和元素都是不可变的。

2.1 格式
  • 格式一: 通过小括号实现

       val/var 元组 = (元素1, 元素2, 元素3....)
    
  • 格式二: 通过箭头来实现

       val/var 元组 = 元素1->元素2
    

    注意: 上述这种方式, 只适用于元组中只有两个元素的情况.

2.2 示例

需求

  1. 定义一个元组,包含学生的姓名和年龄.
  2. 分别使用小括号以及箭头的方式来定义元组.

参考代码

//案例: 演示元组的定义格式 
object ClassDemo06 {
   
	def main(args: Array[String]): Unit = {
    
	//1. 定义一个元组,包含学生的姓名和年龄. 
	//2. 分别使用小括号以及箭头的方式来定义元组. 
	val tuple1 = ("张三", 23)
	val tuple2 = "张三" -> 23 println(tuple1) 
	println(tuple2)
	} 
}
2.3 访问元组中的元素

在Scala中, 可以通过 元组名._编号 的形式来访问元组中的元素,_1表示访问第一个元素,依次类推. 也可以通过 元组名.productIterator 的方式, 来获取该元组的迭代器, 从而实现遍历元组.
格式

  • 格式一: 访问元组中的单个元组.

      	println(元组名._1) //打印元组的第二个元组. 
      	println(元组名._2) //打印元组的第二个元组. 
          ...
    
  • 格式二: 遍历元组

      val tuple1 = (1,2,3,4,5)			//可以有多个值
      val it = tuple1.productIterator	//获取当前元组的迭代器对象
      for(i <- it) println(i)			//打印元组中的所有内容.
    

示例

  1. 定义一个元组,包含一个学生的姓名和性别,“zhangsan”, “male”
  2. 分别获取该学生的姓名和性别, 并将结果打印到控制台上.

参考代码

//案例: 获取元组中的元组. 
object ClassDemo07 {
   
def main(args: Array[String]): Unit = {
   
	//1. 定义一个元组,包含一个学生的姓名和性别,"zhangsan", "male" 
	val tuple1 = "zhangsan" -> "male"
	//2. 分别获取该学生的姓名和性别
	//方式一: 通过 _编号 的形式实现.
	println(s"姓名: ${
     tuple1._1}, 性别: ${
     tuple1._2}")
		//方式二: 通过迭代器遍历的方式实现. 
		//获取元组对应的迭代器对象.
	val it = tuple1.productIterator 
	//遍历元组.
    for(i <- it) println(i)
  }
}

3.列表

列表(List)是Scala中最重要的, 也是最常用的一种数据结构。它存储的数据, 特点是: 有序, 可重复. 在Scala中,列表分为两种, 即: 不可变列表和可变列表.

解释:

  1. 有序 的意思并不是排序, 而是指 元素的存入顺序和取出顺序是一致的 .
  2. 可重复 的意思是 列表中可以添加重复元素
3.1 不可变列表
3.1.1 特点

不可变列表指的是: 列表的元素、长度都是不可变的。

3.1.2 语法
  • 格式一: 通过 小括号 直接初始化.

       val/var 变量名 = List(元素1, 元素2, 元素3...)
    
  • 格式二: 通过 Nil 创建一个空列表.

      val/var 变量名 = Nil
    
  • 格式三: 使用 :: 方法实现.

     val/var 变量名 = 元素1 :: 元素2 :: Nil
    

注意:
使用::拼接方式来创建列表,必须在最后添加一个Nil

3.2.2 示例

需求

  1. 创建一个不可变列表,存放以下几个元素(1,2,3,4)
  2. 使用 Nil 创建一个不可变的空列表
  3. 使用 :: 方法创建列表,包含-2、-1两个元素

参考代码

//案例: 演示不可变列表. 
object ClassDemo08 {
   
	def main(args: Array[String]): Unit = {
   
	//1. 创建一个不可变列表,存放以下几个元素(1,2,3,4) val list1 = List(1, 2, 3, 4)
	//2. 使用`Nil`创建一个不可变的空列表
	val list2 = Nil
	//3. 使用`::`方法创建列表,包含-2、-1两个元素
	val list3 = -2 :: -1 :: Nil
	//4. 打印结果.
	println(s"list1: ${
     list1}")
	println(s"list2: ${
     list2}")
	println(s"list3: ${
     list3}")
	} 
}
3.2 可变列表
3.2.1 特点

可变列表指的是列表的元素、长度都是可变的.

3.2.2 语法
  • 要使用可变列表, 必须先导包.

      import scala.collection.mutable.ListBuffer
    

    小技巧: 可变集合都在 mutable 包中, 不可变集合都在 immutable 包中(默认导入).

  • 格式一: 创建空的可变列表.

      val/var 变量名 = ListBuffer[数据类型]()
    
  • 格式二: 通过 小括号 直接初始化.

       val/var 变量名 = ListBuffer(元素1,元素2,元素3...)
    
3.2.3 示例

需求

  1. 创建空的整形可变列表.
  2. 创建一个可变列表,包含以下元素:1,2,3,4
    参考代码
//1. 导包
import scala.collection.mutable.ListBuffer
//案例: 演示可变列表. 
object ClassDemo09 {
   
	def main(args: Array[String]): Unit = {
   
	//2. 创建空的整形可变列表.
	val list1 = new ListBuffer[Int]()
	//3. 创建一个可变列表,包含以下元素:1,2,3,4 val 	
	list2 = ListBuffer(1, 2, 3, 4) 
	println(s"list1: ${
     list1}") 
	println(s"list2: ${
     list2}")
	} 
}

3.2.4 可变列表的常用操作

关于可变列表的常见操作如下:

格式 功能
列表名(索引) 根据索引(索引从0开始), 获取列表中的指定元素.
列表名(索引) = 值 修改元素值
+= 往列表中添加单个元素
++= 往列表中追加一个列表
-= 删除列表中的某个指定元素
- - = 以列表的形式, 删除列表中的多个元素.
toList 将可变列表(ListBuffer)转换为不可变列表(List)
toArray 将可变列表(ListBuffer)转换为数组

示例

  1. 定义一个可变列表包含以下元素:1,2,3
  2. 获取第一个元素, 并打印结果到控制台.
  3. 添加一个新的元素:4
  4. 追加一个列表,该列表包含以下元素:5,6,7
  5. 删除元素7
  6. 删除元素3, 4
  7. 将可变列表转换为不可变列表
  8. 将可变列表转换为数组
  9. 打印结果.

参考代码

//案例: 演示可变列表的常见操作. 
object ClassDemo10 {
   
	def main(args: Array[String]): Unit = {
    
		//1. 定义一个可变列表包含以下元素:1,2,3 
		val list1 = ListBuffer(1, 2, 3)
		//2. 获取第一个元素, 并打印结果到控制台.
		 println(list1(0))
		//3. 添加一个新的元素:4
		list1 += 4
		//4. 追加一个列表,该列表包含以下元素:5,6,7 
		list1 ++= List(5, 6, 7)
		//5. 删除元素7
		list1 -= 7
		//6. 删除元素3, 4
		list1 --= List(3, 4)
		//7. 将可变列表转换为不可变列表 
		val list2 = list1.toList 
		//8. 将可变列表转换为数组
		val arr = list1.toArray 
		//9. 打印结果. 
		println(s"list1: ${
     list1}") 
		println(s"list2: ${
     list2}")
		 println(s"arr: ${
     arr}")
	} 
}
3.3 列表的常用操作
3.3.1 格式详解

在实际开发中, 我们经常要操作列表, 以下列举的是列表的常用的操作:

格式 功能
isEmpty 判断列表是否为空
++ 拼接两个列表, 返回一个新的列表
head 获取列表的首个元素
tail 获取列表中除首个元素之外, 其他所有的元素
reverse 对列表进行反转, 返回一个新的列表
take 获取列表中的前缀元素(具体个数可以自定义)
drop 获取列表中的后缀元素(具体个数可以自定义)
flatten 对列表进行扁平化操作, 返回一个新的列表
zip 对列表进行拉链操作, 即: 将两个列表合并成一个列表
unzip 对列表进行拉开操作, 即: 将一个列表拆解成两个列表
toString 将列表转换成其对应的默认字符串形式
mkString 将列表转换成其对应的指定字符串形式
union 获取两个列表的并集元素, 并返回一个新的列表
intersect 获取两个列表的交集元素, 并返回一个新的列表
diff 获取两个列表的差集元素, 并返回一个新的列表
3.3.2 示例一: 基础操作

需求

  1. 定义一个列表list1,包含以下元素:1,2,3,4
  2. 使用isEmpty方法判断列表是否为空, 并打印结果.
  3. 再定义一个列表list2,包含以下元素: 4,5,6
  4. 使用 ++ 将两个列表拼接起来, 并打印结果.
  5. 使用head方法,获取列表的首个元素, 并打印结果.
  6. 使用tail方法,获取列表中除首个元素之外, 其他所有的元素, 并打印结果.
  7. 使用reverse方法将列表的元素反转, 并打印反转后的结果.
  8. 使用take方法获取列表的前缀元素, 并打印结果.
  9. 使用drop方法获取列表的后缀元素, 并打印结果.

参考代码

//案例: 演示列表的基础操作. 
object ClassDemo11 {
   
	def main(args: Array[String]): Unit = {
   
		//1. 定义一个列表list1,包含以下元素:1,2,3,4 
		val list1 = List(1, 2, 3, 4)
		//2. 使用isEmpty方法判断列表是否为空, 并打印结果. 
		println(s"isEmpty: ${
     list1.isEmpty}")
		//3. 再定义一个列表list2,包含以下元素: 4,5,6 val 
		list2 = List(4, 5, 6)
		//4. 使用`++`将两个列表拼接起来, 并打印结果. 
		val list3 = list1 ++ list2 println(s"list3: ${
     list3}")
		//5. 使用head方法,获取列表的首个元素, 并打印结果.
		println(s"head: ${
     list3.head}")
		//6. 使用tail方法,获取列表中除首个元素之外, 其他所有的元素, 并打印结果.
		println(s"tail: ${
     list3.tail}")
		//7. 使用reverse方法将列表的元素反转, 并打印反转后的结果.
		val list4 = list3.reverse
		println(s"list4: ${
     list4}")
		//8. 使用take方法获取列表的前缀元素(前三个元素), 并打印结果. 
		println(s"take: ${
     list3.take(3)}")
		//9. 使用drop方法获取列表的后缀元素(除前三个以外的元素), 并打印结果. 
		println(s"drop: ${
     list3.drop(3)}")
	}
}
3.3.3 示例二: 扁平化(压平)

概述
扁平化表示将嵌套列表中的所有具体元素单独的放到一个新列表中. 如下图:

>注意: 如果某个列表中的所有元素都是列表, 那么这样的列表就称之为: 嵌套列表.

在这里插入图片描述

需求

  1. 定义一个列表, 该列表有三个元素, 分别为:List(1,2)、List(3)、List(4,5)
  2. 使用flatten将这个列表转换为List(1,2,3,4,5)
  3. 打印结果.

参考代码

 //案例: 演示扁平化操作. 
 object ClassDemo12 {
   
	def main(args: Array[String]): Unit = {
   
		//1. 定义一个列表, 该列表有三个元素, 分别为:List(1,2)、List(3)、List(4,5)
		val list1 = List(List(1,2), List(3), List(4, 5))
		//2. 使用flatten将这个列表转换为List(1,2,3,4,5)
		val list2 = list1.flatten
		//3. 打印结果
		println(list2)
	} 
}
3.3.4 示例三: 拉链与拉开

概述

  • 拉链:将两个列表,组合成一个元素为元组的列表

    解释: 将列表List(“张三”, “李四”), List(23, 24)组合成列表List((张三,23), (李四,24))

  • 拉开:将一个包含元组的列表,拆解成包含两个列表的元组

    解释: 将列表List((张三,23), (李四,24))拆解成元组(List(张三, 李四),List(23, 24))

需求

  1. 定义列表names, 保存三个学生的姓名,分别为:张三、李四、王五
  2. 定义列表ages, 保存三个学生的年龄,分别为:23, 24, 25
  3. 使用zip将列表names和ages, 组合成一个元素为元组的列表list1
  4. 使用unzip将列表list1拆解成包含两个列表的元组tuple1
  5. 打印结果

参考代码

//案例: 演示拉链与拉开 
object ClassDemo13 {
   
	def main(args: Array[String]): Unit = {
   
		//1. 定义列表names, 保存三个学生的姓名,分别为:张三、李四、王五 
		val names = List("张三", "李四", "王五")
		//2. 定义列表ages, 保存三个学生的年龄,分别为:23, 24, 25
		val ages = List(23, 24, 25)
		//3. 使用zip将列表names和ages, 组合成一个元素为元组的列表list1. 
		val list1 = names.zip(ages)
		//4. 使用unzip将列表list1拆解成包含两个列表的元组tuple1
		val tuple1 = list1.unzip
		//5. 打印结果
		println("拉链: "+ list1)
		println("拉开: " + tuple1)
		} 
}
3.3.5 示例四: 列表转字符串

概述
将列表转换成其对应的字符串形式, 可以通过 toString方法或者mkString方法 实现, 其中

  • toString方法: 可以返回List中的所有元素
  • mkString方法: 可以将元素以指定分隔符拼接起来。

    注意: 默认没有分隔符.

需求

  1. 定义一个列表,包含元素:1,2,3,4
  2. 使用toString方法输出该列表的元素
  3. 使用mkString方法, 用冒号将元素都拼接起来, 并打印结果.

参考代码

//案例: 演示将列表转成其对应的字符串形式. 
object ClassDemo14 {
   
	def main(args: Array[String]): Unit = {
    
		//1. 定义一个列表,包含元素:1,2,3,4
		val list1 = List(1, 2, 3, 4)
		//2. 使用toString方法输出该列表的元素 
		println(list1.toString)
		//简写形式, 因为: 输出语句打印对象, 默认调用了该对象的toString()方法 
		println(list1)
		println("-" * 15)
		//3. 使用mkString方法, 用冒号将元素都拼接起来, 并打印结果. 
		println(list1.mkString(":"))
	} 
}
3.3.6 示例五: 并集, 交集, 差集

概述 操作数据时, 我们可能会遇到求并集, 交集, 差集的需求, 这是时候就要用到union, intersect, diff这些方法了, 其

  • union: 表示对两个列表取并集,而且不去重

    例如: list1.union(list2), 表示获取list1和list2中所有的元素(元素不去重). 如果想要去除重复元素, 则可以通过 distinct 实现.

  • intersect: 表示对两个列表取交集

    例如: list1.intersect(list2), 表示获取list1, list2中都有的元素.

  • diff: 表示对两个列表取差集.

    例如:list1.diff(list2),表示获取list1中有, 但是list2中没有的元素.

需求

  1. 定义列表list1,包含以下元素:1,2,3,4
  2. 定义列表list2,包含以下元素:3,4,5,6
  3. 使用union获取这两个列表的并集
  4. 在第三步的基础上, 使用distinct去除重复的元素
  5. 使用intersect获取列表list1和list2的交集
  6. 使用diff获取列表list1和list2的差集
  7. 打印结果

参考代码

//案例: 演示获取并集, 交集, 差集. 
object ClassDemo15 {
   
	def main(args: Array[String]): Unit = {
    
		//1. 定义列表list1,包含以下元素:1,2,3,4 
		val list1 = List(1, 2, 3, 4)
		//2. 定义列表list2,包含以下元素:3,4,5,6 
		val list2 = List(3, 4, 5, 6)
		//3. 使用union获取这两个列表的并集
		val unionList = list1.union(list2)
		//4. 在第三步的基础上, 使用distinct去除重复的元素
		val distinctList = unionList distinct
		//5. 使用intersect获取列表list1和list2的交集 
		val intersectList = list1.intersect(list2) 
		//6. 使用diff获取列表list1和list2的差集
		val diffList = list1.diff(list2)
		//7. 打印结果
		println("并集, 不去重: " + unionList) 
		println("并集, 去重: "<
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值