Hadoop+Spark大数据技术 第五次作业 第五章 Scala基础与编程

第五次作业
1. 简述Scala语言的基本特性
1. 面向对象:Scala是一种完全面向对象的语言。其每一种数据类型都是一个对象,这使得它具有非常统一的模型。
2. 函数式编程:Scala同时支持函数式编程,它拥有高阶函数、闭包、不可变数据结构、递归等函数式编程的关键特性。
3. 扩展性:Scala的语法非常灵活,允许开发者自定义运算符和语法糖。也支持模式匹配、类型推断和匿名函数等高级特性,这些都为编写简洁、高效的代码提供了可能。此外,Scala的语法允许在单个文件中定义类、对象、函数等,使得代码组织更加灵活。
4. 并发性:Scala支持Actor模型(处理并发的轻量级机制)。通过Actor,可以编写出线程安全的、易于管理的并发代码,有效地利用多核处理器资源。
5. 可以和Java混编:Scala运行在Java虚拟机(JVM)上,并兼容Java的API。可以直接使用Java库,或者在Scala代码中调用Java方法,反之亦然。这为已有的Java项目提供了无缝迁移到Scala的可能,也使得Scala成为一个非常实用的工具,可以在不完全重构的情况下逐步引入新的编程范式。
2. 简述Scala语言的9种基本数据类型。 说明关键字Unit、Nothing、Any的含义。

Unit无返回值,通常用于不返回任何内容的方法。
Nothing是任何其他类型的子类,用于表示永远不会正常终止的程序部分。
Any是所有其他类型的超类(父类)
3. 简述Scala中数组、列表、集合、元组、映射的名称及特点。
数组(Array):固定大小的集合,元素类型相同,性能较好但不支持动态修改大小。
列表(List):不可变的序列集合,适合于递归处理和模式匹配,但头部插入和删除效率低。
集合(Set):无序且不重复元素的集合,分为可变和不可变两种。
元组(Tuple):固定长度、不同类型的元素组合,最多支持22个元素,常用于同时携带多种类型信息。
映射(Map):键值对的集合,键唯一,分为可变和不可变两种,适合快速查找。
4. 举例说明匿名函数和高阶函数的含义,
匿名函数
也称为Lambda函数。箭头“=>”定义,箭头的左边是参数列表,箭头的右边是表达式,表达式的值即匿名函数的返回值。 在代码中直接定义的函数,没有具体的函数名。通常用于一些简单的、一次性的操作。
val sum = (x: Int, y: Int) => x + y
val result = sum(3, 5) /
/ result = 8
高阶函数
高阶函数是指使用其他函数作为参数,或者返回一个函数作为结果的函数。
val numbers = List(1, 2, 3, 4)
val doubled = numbers.map(x => x * 2)
// doubled = List(2, 4, 6, 8)
5. 阅读、分析下列程序段,并给出运行结果。
(1)
var v = 0
for (i <- 1 to 9) {
for (j <- 1 to i) {
v = i*j
print(f"$j%s*$i%s=$v%-3s")
}
println()
}
(2)
val a = Array("Hello Spark","Hello Hadoop","Hello Scala")
val b = a.flatMap(_.split(" ")).map((_,1)).groupBy(t => t._1).map(t => (t._1,t._2.length)).toList.sortBy(t => t._2).reverse
b.foreach(x => println(x))
(3)
class Person(val namec:String,val agec:Int) {
var name:String = namec
var age:Int = agec
def printPerson() : Unit = {
printf(f"name:$name%8s, age:$age%-4d")
}
}
object Test2 {
def main(args:Array[String]):Unit = {
val x = new Person("zhang",21)
x.printPerson()
}
}
(4)
val a = List(("a",85),("b",95),("c",75),("a",95))
a.groupBy(_._1)
(5)
val s = List("Spark","Python","Hadoop","HBase")
s.foreach(e => print(e+" "))
print(s.count(e => e.length == 5))
(1) 打印九九乘法表
var v = 0
for (i <- 1 to 9) {
for (j <- 1 to i) {
v = i*j
print(f"$j%s*$i%s=$v%-3s") // 使用格式化字符串打印乘法公式
}
println() // 每行结束后换行
}
代码分析:
var v = 0: 定义一个变量v用于存储乘积结果,初始值为 0。for (i <- 1 to 9): 外层循环遍历 1 到 9 的数字,代表乘法表的行数。for (j <- 1 to i): 内层循环遍历 1 到当前行数i的数字,代表乘法表的列数。v = i*j: 计算当前行i和当前列j的乘积,并将结果存储在v中。print(f"$j%s*$i%s=$v%-3s"): 使用格式化字符串f""打印乘法公式。$j%s: 打印当前列数j,并使用%s保持字符串格式。*$i%s: 打印乘号和当前行数i,并使用%s保持字符串格式。=$v%-3s: 打印等号和乘积结果v,并使用%-3s将结果左对齐,宽度为 3 个字符。
println(): 每行结束后换行,确保乘法表格式正确。
(2) 统计单词出现次数并排序
val a = Array("Hello Spark","Hello Hadoop","Hello Scala")
val b = a.flatMap(_.split(" ")).map((_,1)).groupBy(t => t._1).map(t => (t._1,t._2.length)).toList.sortBy(t => t._2).reverse
b.foreach(x => println(x))
代码分析:
val a = Array("Hello Spark","Hello Hadoop","Hello Scala"): 定义一个包含三个字符串的数组a。val b = a.flatMap(_.split(" ")).map((_,1)).groupBy(t => t._1).map(t => (t._1,t._2.length)).toList.sortBy(t => t._2).reverse: 一系列操作,统计每个单词出现的次数,并按照次数降序排序。flatMap(_.split(" ")): 将数组a中的每个字符串按空格分割成单词,并将所有单词扁平化到一个新的数组中。map((_,1)): 将每个单词转换为一个元组,第一个元素为单词本身,第二个元素为 1,表示该单词出现一次。groupBy(t => t._1): 按单词分组,将相同单词的元组放在一起。map(t => (t._1,t._2.length)): 将每个分组转换为一个新的元组,第一个元素为单词,第二个元素为该单词出现的次数。toList: 将结果转换为 List。sortBy(t => t._2): 按单词出现次数升序排序。reverse: 将排序结果逆序,实现降序排序。
b.foreach(x => println(x)): 遍历排序后的 Listb,并打印每个元组,即单词和出现次数。
(3) 定义 Person 类并创建对象
class Person(val namec:String,val agec:Int) {
var name:String = namec
var age:Int = agec
def printPerson() : Unit = {
printf(f"name:$name%8s, age:$age%-4d")
}
}
object Test2 {
def main(args:Array[String]):Unit = {
val x = new Person("zhang",21)
x.printPerson()
}
}
代码分析:
class Person(val namec:String,val agec:Int): 定义一个名为Person的类,包含两个参数namec和agec,分别代表姓名和年龄。val namec:String,val agec:Int: 声明两个参数,并使用val修饰,表示参数的值在对象创建后不可变。
var name:String = namec: 定义一个名为name的可变变量,用于存储姓名,并将其初始化为参数namec的值。var age:Int = agec: 定义一个名为age的可变变量,用于存储年龄,并将其初始化为参数agec的值。def printPerson() : Unit = { ... }: 定义一个名为printPerson的方法,用于打印 Person 对象的姓名和年龄。printf(f"name:$name%8s, age:$age%-4d"): 使用格式化字符串f""打印姓名和年龄。name:$name%8s: 打印 "name:" 和 姓名,并使用%8s将姓名右对齐,宽度为 8 个字符。age:$age%-4d: 打印 "age:" 和 年龄,并使用%-4d将年龄左对齐,宽度为 4 个字符。
object Test2: 定义一个名为Test2的对象,包含main方法。def main(args:Array[String]):Unit = { ... }: 定义main方法,用于执行程序。val x = new Person("zhang",21): 创建一个名为x的Person对象,并传入姓名 "zhang" 和年龄 21 作为参数。x.printPerson(): 调用x对象的printPerson方法,打印 Person 对象的姓名和年龄。
(4) 使用 groupBy 对 List 进行分组
val a = List(("a",85),("b",95),("c",75),("a",95))
a.groupBy(_._1)
代码分析:
val a = List(("a",85),("b",95),("c",75),("a",95)): 定义一个包含四个元组的 Lista。a.groupBy(_._1): 使用groupBy方法对a进行分组,按照每个元组的第一个元素进行分组。_._1: 使用下划线_表示匿名函数,并使用._1提取每个元组的第一个元素。
(5) 遍历 List 并统计长度为 5 的元素个数
val s = List("Spark","Python","Hadoop","HBase")
s.foreach(e => print(e+" "))
print(s.count(e => e.length == 5))
代码分析:
val s = List("Spark","Python","Hadoop","HBase"): 定义一个包含四个字符串的 Lists。s.foreach(e => print(e+" ")): 使用foreach方法遍历s中的每个元素,并打印每个元素后加一个空格。e => print(e+" "): 匿名函数,将每个元素e打印出来,并在后面加一个空格。
print(s.count(e => e.length == 5)): 使用count方法统计s中长度为 5 的元素个数,并打印结果。e => e.length == 5: 匿名函数,判断每个元素e的长度是否等于 5。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)