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)): 遍历排序后的 List b,并打印每个元组,即单词和出现次数。

(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)): 定义一个包含四个元组的 List a
  • 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"): 定义一个包含四个字符串的 List s
  • 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。

  • 26
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值