spark基础学习笔记12:scala内建控制结构

howard2005      2022-04-25     760

关键词:

文章目录

零、本讲学习目标

  1. 掌握条件表达式
  2. 掌握各种循环
  3. 理解流间变量绑定
  4. 掌握yield语句的使用
  5. 掌握异常处理语句
  6. 了解match语句的使用
  7. 理解变量作用域

Scala提供的控制结构并不算多,因为在函数式编程中,可以自己开发出各种功能的控制结构,所以Scala提供的原生控制结构仅仅够用为止。

一、条件表达式

(一)语法格式

if (条件)1 else2

(二)执行情况

  • 条件为真,结果是值1;条件为假,结果是值2。如果if和else的返回结果同为某种类型,那么条件表达式结果也是那种类型,否则就是Any类型

(三)案例演示

任务1、根据输入值的不同进行判断

  • 当然也可以在一个表达式中进行多次判断
  • 可以将上述条件表达式改造成嵌套的选择结构,可读性倒是提高了,但是简洁性降低了

任务2、编写Scala程序,判断奇偶性

  • 打开Scala项目ScalaDemo2022,创建net.hw.structure包,在包里创建Example01对象
package net.hw.structure

import scala.io.StdIn

object Example01 
  def main(args: Array[String]): Unit = 
    print("n = ")
    val n = StdIn.readLine().toInt
    if (n % 2 == 0) 
      println(n.toString + "是偶数")
     else 
      println(n.toString + "是奇数")
    
  

  • 运行程序,查看结果

  • 利用if结构具有返回值的特性,改写程序

  • 运行程序,查看结果

二、块表达式

(一)语法格式

语句组
  • 块表达式为包含在符号“”中的语句块

(二)执行情况

  • 需要注意的是,Scala中的返回值是最后一条语句的执行结果,而不需要像Java一样单独写return关键字。如果表达式中没有执行结果,就返回一个Unit对象,类似Java中的void。

(三)案例演示

  • 语句块最后一句的值就是整个块表达式的结果
  • 语句块最后一句没有执行结果,那么块表达式结果就是Unit

三、for循环

(一)单重for循环

1、语法格式

for (变量 <- 集合或数组 (条件)) 
     语句组

2、执行情况

  • 表示将集合或数组中的每一个值循环赋给一个变量

3、案例演示

任务1:输出1到10

  • 两种方式实现
  • Range(a, b): 从a到b,不包含b,跟Python里的range函数一样,含头不含尾
  • 1 to 10表示将1到10的所有值组成一个集合,且包括10。若不想包括10,则可使用关键字until

任务2、遍历字符串,输出每个字符

  • 方法一、按索引取字符串的每个字符
  • 方法二:将字符串看作一个由多个字符组成的集合
  • 从Scala2.13.0开始,其它类型数据与字符进行+运算,会抛出警告信息
  • cChar类型,因此需要调用toString方法,将其转换成字符串,才能与其它字符串连接

任务3、计算 1 + 2 + 3 + … + 100

  • 注意sum必须定义为var型变量

任务4、输出列表内的偶数

  • 采用两种方式来实现

任务5、输出全部两位素数

for (n <- 10 to 100; if !(n % 2 == 0 || n % 3 == 0 || n % 5 == 0 || n % 7 == 0))
    print(n.toString + " ")

(二)嵌套for循环

1、语法格式

  • 传统格式
for (变量1 <- 集合或数组)
    for (变量2 <- 集合或数组) 
       语句组
    

  • 特有格式
for (变量1 <- 集合或数组; 变量2 <- 集合或数组 (条件)) 
   语句组

2、案例演示

任务1、打印九九表

方法一、采用双重循环来实现
  • 在项目ScalaDemo2022里创建Example02对象
package net.hw.structure

/**
  * 功能:双重循环打印九九表
  * 作者:华卫
  * 日期:2022年3月6日
  */
object Example02 
  def main(args: Array[String]): Unit = 
    for (i <- 1 to 9) 
      for (j <- 1 to i)
        print(i.toString + "×" + j + "=" + (i * j) + "\t")
      println()
    
  

  • 运行程序,查看结果
方法二、采用单重循环来实现
  • 在项目ScalaDemo2022里创建Example03对象
package net.hw.structure

/**
  * 功能:单重循环打印九九表
  * 作者:华卫
  * 日期:2022年3月6日
  */
object Example03 
  def main(args: Array[String]): Unit = 
    for (i <- 1 to 9; j <- 1 to i) 
      print(i.toString + "×" + j + "=" + (i * j) + "\t")
      if (i == j) println()
    
  

  • 运行程序,查看结果
方法三、采用单重循环与流间变量绑定来实现
  • 在项目ScalaDemo2022里创建Example04对象
  • 在for循环头里sep = if (i == j) "\r\n" else "\t"就是流间变量绑定
package net.hw.structure

/**
  * 功能:单重循环与流间变量绑定打印九九表
  * 作者:华卫
  * 日期:2022年03月06日
  */
object Example04 
  def main(args: Array[String]): Unit = 
    for (i <- 1 to 9; j <- 1 to i; sep = if (i == j) "\r\n" else "\t")
      print(i.toString + "×" + j + "=" + (i * j) + sep)
  

  • 运行程序,查看结果
方法四、采用单重循环、流间变量与yield来实现
  • for循环语句本身的返回值是Unit类型,无论在循环体中返回什么都是无效的,最终得到的都是Unit的值,但是可以在循环中的循环条件和循环体之间加上yield关键字,那么就可以将循环体产生的返回值组成数组进行返回。
  • 在项目ScalaDemo2022里创建Example05对象
package net.hw.structure

/**
  * 功能:采用单重循环、流间变量与yield打印九九表
  * 作者:华卫
  * 日期:2022年03月06日
  */
object Example05 
  def main(args: Array[String]): Unit = 
    val list = for (i <- 1 to 9; j <- 1 to i; sep = if (i == j) "\r\n" else "\t")
      yield i.toString + "×" + j + "=" + (i * j) + sep
    for (x <- list) print(x)
  


  • 运行程序,查看结果

任务2、去掉对角线

  • 一个三阶方阵,单元格的值是行号与列号的乘积,去掉对角线,输出剩余元素
  • 方法一、传统双重循环
  • 方法二、特有双重循环

课堂练习:编程求解百钱买百鸡问题

  • 我国古代数学家张丘建在《算经》一书中曾提出过著名的“百钱买百鸡”问题,该问题叙述如下:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?
  • 翻译过来,意思是公鸡一个五块钱,母鸡一个三块钱,小鸡三个一块钱,现在要用一百块钱买一百只鸡,问公鸡、母鸡、小鸡各多少只?

四、条件循环

(一)while循环

1、语法格式

  • Scala的while循环与Java类似
while(条件)    
   循环体

2、案例演示

任务1、计算1+ 2 + 3 + … + 100

  • 注意:sum必须是变量
  • 采用函数式风格来写代码,递归函数来实现求和,注意:此处sum是常量

任务2、打印全部水仙花数

  • 所谓水仙花数,是指等于其各位数字立方和的三位数。

\qquad 153 = 1 3 + 5 3 + 3 3 153=1^3+5^3+3^3 153=13+53+33
\qquad 370 = 3 3 + 7 3 + 0 3 370=3^3+7^3+0^3 370=33+73+03
\qquad 371 = 3 3 + 7 3 + 1 3 371=3^3+7^3+1^3 371=33+73+13
\qquad 407 = 4 3 + 0 3 + 7 3 407=4^3+0^3+7^3 407=43+03+73

  • 对于[100, 999]范围的每个数n,我们要去判断它是否等于其各位数字的立方和,这里的难点或关键在于如何分解一个三位数,得到它的每位数字。

  • 假设我们已经把三位数n分解成百位数p3,十位数p2,个位数p1,
    这样我们的筛选条件就可以写出来:n == p3 * p3 * p3 + p2 * p2 * p2 + p1 * p1 * p1。

  • 如何拆分一个三位数n呢?

  • 首先求n的个位数:n % 10
    然后要将三位数变成两位数:n = n / 10;
    对于新的两位数n,又求它的个位数:n % 10
    然后要将两位数变成一位数:n = n / 10;

  • 也就是说我们可以交替使用求余和整除运算将一个三位数拆分,得到它的个位数、十位数和百位数。当然这个分解方法可以推广到任何多位数的拆分。

  • net.hw.structure包里创建Example06对象

package net.hw.structure

/**
  * 功能:打印水仙花数
  * 作者:华卫
  * 日期:2022年03月06日
  */
object Example06 
  def main(args: Array[String]): Unit = 
    for (n <- 100 to 999) 
      val p1 = n % 10     // 个位数
      val p2 = n / 10 % 10 // 十位数
      val p3 = n / 100     // 百位数
      if (n == p1 * p1 * p1 + p2 * p2 * p2 + p3 * p3 * p3)
        println(n.toString + " = " + p3 + "^3 + " + p2 + "^3 + " + p1 + "^3")
    
  

  • 运行程序,查看结果

(二)do while循环

  • 与Java语言一样,do while循环与while循环类似,但是do while循环会确保至少执行一次循环。

1、语法格式

do 
   循环体
 while(条件)

2、案例演示

任务:计算1+ 2 + 3 + … + 100

五、异常处理

(一)异常处理概述

  • Scala中继承了Java的异常机制,提供了程序中产生意外情况时处理的机制,抛出异常的过程和Java中基本一致,通过throw关键字进行:throw XxxException(),一旦抛出可以当场捕获处理或接着向上抛,捕获异常是通过 try-catch-finally来实现的。

(二)案例演示

任务:演示try-catch-finally

  • try-catch是有返回值的:如果没有异常就是try语句的返回值,如果有异常就是catch语句的返回值。注意不会是finally的返回值,finally即使有返回值,也会被抛弃,这点和Java是不同的。
  • net.hw.structure包里创建Example07对象
package net.hw.structure

import java.io.IOException

/**
  * 功能:演示异常处理
  * 作者:华卫
  * 日期:2022年03月06日
  */
object Example07 
  def main(args: Array[String]): Unit = 
    var message = ""
    val result = try 
      mx()
      "恭喜,程序执行正常!"
     catch 
      case e: NullPointerException => "空指针异常"
      case e: IOException => "呵呵,I/O异常~"
      case e: Exception => "管它呢,反正是异常~"
     finally 
      message = "程序到此为止!"
      "无论是否有异常,都会执行finally里的语句~"
    
    println(result)
    println(message)
  

  def mx(): Unit = 
    throw new RuntimeException("随便抛出一个异常~")
  

  • 执行程序,查看结果(此时有异常,result取的是catch里的返回值 - 管它呢,反正是异常~,finally语句块执行了的,因此message可以打印出来 - 程序到此为止!

  • 注释掉mx()方法里的语句

  • 执行程序,查看结果(此时有异常,result取的是try里的返回值 - 恭喜,程序执行正常!

  • 在Scala里,finally的返回值不会覆盖try和catch的返回值,这一点跟Java不同。

  • 运行程序,查看结果(此时运行test()方法,调用mx()方法抛出异常,执行catch语句块,返回异常~,但是要被finally语句块的返回值停止!覆盖,因此最终输出的就是停止!

  • 我们把mx()方法里的抛出异常的语句注释掉,此时程序正常运行,但是test()方法的返回值不会是正常~,还是会被finally语句块的返回值覆盖,成为停止!

六、match结构

(一)语法格式

变量 match 
      case1 => 表达式1或语句1
      case2 => 表达式2或语句2
      case3 => 表达式3或语句3
      ……
      case _ => 表达式n或语句n
    
  • Scala中的match类似于其他语言的switch。与Java不同的是,match语句可以应用在任何类型量或表达式上,另外需要调用break语句,match默认执行完一个case后直接跳出match结构。注意,match是具有返回值的,就是被选到的case的值。

(二)案例演示

任务:给城市下评语

  • net.hw.structure包里创建Example08对象
package net.hw.structure

import scala.io.StdIn

/**
  * 功能:演示match语句
  * 作者:华卫
  * 日期:2022年03月06日
  */
object Example08 
  def main(args: Array[String]): Unit = 
    print("输入城市:")
    val city = StdIn.readLine();
    val comment = city match 
      case "北京" => "伟大的首都"
      case "上海" => "神奇的魔都"
      case "泸州" => "醉人的酒城"
      case _ => "一般的城市"
    
    print(city + ": " + comment)
  

  • 运行程序,查看结果

七、变量作用域

(一)Java变量作用域

  • Java中根据不同大括号区分变量作用范围,不允许有叠加,外部看不到内部,内部能看到外部。

1、内部能访问外部

2、外部不能看内部

(二)Scala变量作用域

  • Scala中根据不同大括号区分变量作用范围,不允许有叠加,外部看不到内部,内部看不到外部。

1、内部不能访问外部

  • net.hw.structure包创建Example09对象

2、外部不能访问内部

  • net.hw.structure包创建Example10对象

八、补充案例

任务:评定成绩等级

1、编写符合函数式编程风格的Sala程序

    scala学习笔记3:基本控制结构基础

    以下主要记录的是看完scalainprogramming这本书buildincontrolstructures(第七章)后的要点总结。1,if,while,dowhile和for的用法和java类似,不过for语句中可以带filter。1valfilesHere=(newFile(".")).listFiles()2for(file<-filesHereiffile.getName.ends 查看详情

    大数据处理学习笔记1.5掌握scala内建控制结构(代码片段)

    文章目录零、本讲学习目标一、条件表达式(一)语法格式(二)执行情况(三)案例演示任务1、根据输入值的不同进行判断任务2、编写Scala程序,判断奇偶性二、块表达式(一)语法格式ÿ... 查看详情

    spark基础学习笔记09:scala基础(代码片段)

    ...模式。下面我们将在Scala的命令行操作模式中学习Scala的基础知识。一、变量声明(一)简单说明Scala中变量的声明使用关键字val和var。val类似Java中的final变量,也就是常量,一旦初始化将 查看详情

    spark基础学习笔记13:scala函数(代码片段)

    文章目录零、本讲学习目标一、声明函数(一)显式声明函数1、声明格式2、注意事项3、案例演示(二)隐式声明函数1、声明格式2、注意事项3、案例演示二、Scala函数种类(一)成员方法1、基本概念2、... 查看详情

    spark基础学习笔记14:scala数据结构(代码片段)

    文章目录零、本讲学习目标一、数组(Array)(一)定长数组1、数组定义(1)定义数组时初始化数据(2)定义时指定数组长度,后赋值2、数组遍历(1)传统for循环方式(2)增强for循环方... 查看详情

    spark基础-scala学习(集合)(代码片段)

    集合scala的集合体系结构ListLinkedListSet集合的函数式编程函数式编程综合案例:统计多个文本内的单词总数scala的集合体系结构scala中的集合体系主要包括:Iterable、Seq、Set、Map。其中Iterable是所有集合trait的根trait。这个结构与java... 查看详情

    spark基础学习笔记10:scala集成开发环境(代码片段)

    ...境会在两种集成开发环境里创建Scala项目在上一讲《Spark基础学习笔记09:Scala基础》里,我们都是利用ScalaShell交互式环境来学习Scala基础知识,虽然交互式有快捷的优点,但是要写比较完整的程序,编辑就显得... 查看详情

    内建控制结构

    Scala里没有多少内建控制结构。仅有的包括if,while,for,try,match和函数调用。如此之少的理由是,从一开始Scala就包括了函数文本。代之以在基本语法之上一个接一个添加高层级控制结构,Scala把它们汇集在库里.有件你会注意... 查看详情

    scala学习笔记一之基础语法,条件控制,循环控制,函数,数组,集合

    ...安装教程:http://www.cnblogs.com/biehongli/p/8065679.html1:Scala之基础语法学习笔记:1:声明val变量:可以使用val来声明变量,用来存放表达式的计算结果,但是常量声明后是无法改变它的值的,建议使用val来声明常量;声明var变量:如果要... 查看详情

    spark快速开发之scala基础之2控制流程

    判断结构大体与java相当。scala没有三元表达式。valnum=if(1>0)1else0//相当于匿名函数println(num)varnum2=0if(1>0)num2=1elsenum2=0println(num2) 选择结构match。与java的stiwch相当。但scala的match强大很多。 通配符匹配(WildcardPatternMatchi 查看详情

    spark基础学习笔记08:scala简介与安装(代码片段)

    文章目录零、本讲学习目标一、Scala简介(一)Scala概述(二)函数式编程(三)Scala特性1、一切都是对象2、一切都是函数3、一切都是表达式(四)在线运行Scala二、Windows上安装Scala(一)... 查看详情

    三万字,spark学习笔记

    Spark基础Spark特性Spark使用简练优雅的Scala语言编写,基于Scala提供了交互式编程体验,同时提供多种方便易用的API。Spark遵循“一个软件栈满足不同应用场景”的设计理念,逐渐形成了一套完整的生态系统(包括Spar... 查看详情

    spark基础学习笔记22:sparkrdd案例分析

    文章目录零、本讲学习目标一、案例分析:SparkRDD实现单词计数(一)案例概述(二)实现步骤1、新建Maven管理的Spark项目2、添加Scala和Spark依赖3、创建WordCount对象4、对于程序代码进行解析5、将Spark项目编译和... 查看详情

    三万字,spark学习笔记(代码片段)

    Spark基础Spark特性Spark使用简练优雅的Scala语言编写,基于Scala提供了交互式编程体验,同时提供多种方便易用的API。Spark遵循“一个软件栈满足不同应用场景”的设计理念,逐渐形成了一套完整的生态系统(包括Spar... 查看详情

    scala中的控制结构(代码片段)

      所谓的内建控制结构是指编程语言中可以使用的一些代码控制语法,如Scala中的if,while,for,try,match,以及函数调用等。需要注意的是,Scala几乎所有的内建控制结构都会返回一个值,这是由于函数式编程语言被认为是... 查看详情

    spark基础学习笔记24:sparksql数据源

    文章目录零、本讲学习目标一、基本操作(一)默认数据源1、默认数据源Parquet2、案例演示读取Parquet文件(1)在SparkShell中演示(2)通过Scala程序演示(二)手动指定数据源1、format()与option()方法概... 查看详情

    2022年spark基础学习笔记

    ...、Spark学习笔记在OpenStack私有云上创建与配置虚拟机Spark基础学习笔记01:初步了解SparkSpark基础学习笔记02:Spark运行时架构Spark基础学习笔记03:搭建Spark单机版环境Spark基础学习笔记04:搭建Spark伪分布式环境Spark基础学习笔记05:... 查看详情

    spark基础-scala学习(代码片段)

    函数式编程将函数赋值给变量匿名函数高阶函数高级函数的类型推断scala的常用高阶函数闭包sam转换currying函数return将函数赋值给变量scala中的函数是一等公民,可以独立定义,独立存在,而且可以直接将函数作为值赋值给变量sca... 查看详情