大数据课堂记录1.5 掌握Scala内建控制结构

目录

本节学习目标

一、条件表达式

(一)语法格式

(二)执行情况

(三)案例演示

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

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

 二、块表达式

(一)语法格式

(二)执行情况

(三)案例演示

三、for循环

(一)单重for循环

1、语法格式

2、执行情况

3、案例演示

(二)嵌套for循环

         1、语法格式

2、案例演示

四、条件循环

(一)while循环

1、语法格式

2、案例演示

(二)do while循环

1、语法格式

2、案例演示

五、异常处理

(一)异常处理概述

(二)案例演示

 六、match结构

(一)语法格式

(二)案例演示

任务:给城市下评语

七、变量作用域

(一)Java变量作用域

1、内部能访问外部

2、外部不能看内部 

(二)Scala变量作用域 

1、内部不能访问外部

2、外部不能访问内部

八、补充案例

任务:评定成绩等级 

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

2、函数式风格的程序有几个特点

3、非函数式风格的程序


本节学习目标

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

一、条件表达式

(一)语法格式

if (条件) 值1 else 值2

(二)执行情况

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

(三)案例演示

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

  •  当然也可以在一个表达式中进行多次判断

  • 可以将上述条件表达式改造成嵌套的选择结构,可读性倒是提高了,但是简洁性降低了 

  •  利用选择表达式评定学生成绩等级

  • 函数式编程语言,只有一个入口和一个出口,中间没有任何与外界交流的输入或输出语句,所以安全性非常好。

  • Java不是函数式语言,选择结构没有返回值,就必须根据不同情况对评语变量赋值。

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

  • 打开Scala项目ScalaDemo,创建net.huawei.day02包,在包里创建Example01对象
package net.liujuan.day02

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结构具有返回值的特性,改写程序成为函数式风格

package net.liujuan.day02

import scala.io.StdIn

object Example01 {
  def main(args: Array[String]): Unit = {
    print("n = ")
    val n = StdIn.readLine.toInt
    val result = if (n % 2 == 0) n.toString + "是偶数~" else n.toString + "是奇数~"
    println(result)
  }
}
  • 运行程序,查看结果 

 二、块表达式

(一)语法格式

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

(二)执行情况

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

(三)案例演示

  • 语句块最后一句的值就是整个块表达式的结果

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

三、for循环

(一)单重for循环

1、语法格式

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

2、执行情况

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

3、案例演示

任务1:输出1到10

  • 两种方式实现,一种使用Range类,一种使用to运算符

 

  • Range(a, b): 从a到b,不包含b,跟Python里的range函数一样,含头不含尾

  • 1 to 10表示将1到10的所有值组成一个集合,且包括10。若不想包括10,则可使用关键字until

  • 用Java语言完成任务 

 

  • 用Python语言完成任务

  • 打印字符直角三角形 

  •  利用map函数产生每行星号构成的向量,然后利用foreach函数循环输出

  • 利用双重循环与流间变量,这个是Scala语言特有的东西

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

  • 方法一、按索引取字符串的每个字符(传统for循环)

  •  方法二:将字符串看作一个由多个字符组成的集合(增强for循环)

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

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

  •  利用集合的归并方法来求和最简单

 任务4、输出列表内的偶数(过滤)

  • 采用三种方法来实现

  •  采用Java语言实现

  •  采用Python语言实现

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

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

(10 to 100).filter(n => !(n % 2 == 0 || n % 3 == 0 || n % 5 == 0 || n % 7 == 0))

 

(二)嵌套for循环

1、语法格式

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

2、案例演示

任务1、打印九九表

方法一、采用双重循环来实现

net.liujuan.day02包里创建Example02对象

package net.liujuan.day02
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()
    }
  }
}
  •   运行程序,查看结果

 方法二、采用单重循环来实现

  • net.liujuan.day02包里创建Example03对象

package net.liujuan.day02
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 (j == i) println()
    }
  }
}
  • 运行程序,查看结果

 方法三、采用单重循环与流间变量绑定来实现

  • net.liujuan.day02包里创建Example04对象
  • 在for循环头里sep = if (i == j) "\n" else "\t"就是流间变量绑定

package net.liujuan.day02
object Example04 {
  def main(args: Array[String]): Unit = {
    for (i <- 1 to 9; j <- 1 to i; sep = if (j == i) "\n" else "\t") {
      print(i.toString + "×" + j + "=" + (i * j) + sep)
    }
  }
}
  • 运行程序,查看结果

 方法四、采用单重循环、流间变量与yield来实现

  • for循环语句本身的返回值是Unit类型,无论在循环体中返回什么都是无效的,最终得到的都是Unit的值,但是可以在循环中的循环条件和循环体之间加上yield关键字,那么就可以将循环体产生的返回值组成数组进行返回。
  • net.liujuan.day02包里创建Example05对象

package net.liujuan.day02
object Example05 {
  def main(args: Array[String]): Unit = {
    val list = for (i <- 1 to 9; j <- 1 to i; sep = if (j == i) "\n" else "\t")
      yield i.toString + "×" + j + "=" + (i * j) + sep
    list.foreach(print)
  }
}
  • 运行程序,查看结果

任务2、去掉对角线 

  • 一个三阶方阵,单元格的值是行号与列号的乘积,去掉对角线,输出剩余元素

  • 方法一、传统双重循环 

package net.liujuan.day02
object Example06 {
  def main(args: Array[String]): Unit = {
    for (i <-1 to 3) {
      for (j <- 1 to 3) {
        if (i != j)
          print((i * j).toString + "\t")
        else
          print("\t")
      }
      println()
    }
  }
}
  • 运行程序,查看结果

  •  方法二、特有双重循环

package net.liujuan.day02
object Example07 {
  def main(args: Array[String]): Unit = {
    for (i <- 1 to 3; j <- 1 to 3; sep = if (i == j) "\t" else (i * j).toString + "\t") {
      print(sep)
      if (j == 3) println()
    }
  }
}
  • 运行程序,查看结果

  •  方法三:采用两个流间变量和yield

package net.liujuan.day02
object Example08 {
  def main(args: Array[String]): Unit = {
    val list = for (i <- 1 to 3; j <- 1 to 3; sep = if (j == 3) "\n" else "\t";
                    str = if (i != j) (i * j).toString + sep else " " + sep) yield str
    list.foreach(print)
  }
}
  •  运行程序,查看结果

四、条件循环

(一)while循环

1、语法格式

  • Scala的while循环与Java类似

while(条件) {   
   循环体
}

2、案例演示

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

  • net.liujuan.day02包里创建Example10对象

  • 注意:isum必须是变量

package net.liujuan.day02
object Example10 {
  def main(args: Array[String]): Unit = {
    var sum = 0
    var i = 1
    while (i <= 100) {
      sum = sum + i
      i = i + 1
    }
    println("1 + 2 + 3 + ... + 100 = " + sum)
  }
}
  • 运行程序,查看结果

  • 采用函数式风格来写代码,递归函数来实现求和,注意:此处sum是常量
  • net.liujuan.day02包里创建Example10_对象

 

package net.liujuan.day02
object Example10_ {
  def mx(n: Int, sum: Int): Int = {
    if (n > 0) mx(n - 1, sum + n) else sum
  }

  def main(args: Array[String]): Unit = {
    println("1 + 2 + 3 + ... + 100 = " + mx(100, 0))
  }
}
  • 运行程序,查询结果

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

net.liujuan.day02包里创建Example11对象

package net.liujuan.day02
object Example11 {
  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 

net.liujuan.day02包里创建Example12对象

package net.liujuan.day02
object Example12 {
  def main(args: Array[String]): Unit = {
    var sum = 0
    var i = 1
    do {
      sum = sum + i
      i = i + 1
    } while (i <= 100)
    println("1 + 2 + 3 + ... + 100 = " + sum)
  }
}
  • 运行程序,查看结果

五、异常处理

(一)异常处理概述

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

 (二)案例演示

任务:演示try-catch-finally

net.liujuan.day02包里创建Example13对象

package net.liujuan.day02
import java.io.IOException
object Example13 {
  def main(args: Array[String]): Unit = {
    var message = ""
    val result = try {
      mx() // 调用方法,会抛出异常
      "恭喜,程序执行正常~"
    } catch {
      case e: NullPointerException => "空指针异常~"
      case e: IOException => "呵呵,这是I/O异常~"
      case e: RuntimeException => "哈哈,这是运行时异常~"
      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 {
      case 值1 => 表达式1或语句1
      case 值2 => 表达式2或语句2
      case 值3 => 表达式3或语句3
      ……
      case _ => 表达式n或语句n
    }

  • Scala中的match(匹配)类似于其他语言的switch(开关)。与Java不同的是,match语句可以应用在任何类型量或表达式上,另外不需要调用break语句,match默认执行完一个case后直接跳出match结构。注意,match是具有返回值的,就是被选到的case的值。

(二)案例演示

任务:给城市下评语

net.liujuan.day02包里创建Example14对象

package net.liujuan.day02
import scala.io.StdIn
object Example14 {
  def main(args: Array[String]): Unit = {
    print("输入城市:")
    val city = StdIn.readLine()
    val comment = city match {
      case "北京" => "是伟大的首都~"
      case "上海" => "是神奇的魔都~"
      case "广州" => "是迷人的妖都~"
      case "泸州" => "是醉人的酒城~"
      case _ => "是普通的城市~"
    }
    println(city + comment)
  }
}
  •  运行程序,查看结果

 

 

七、变量作用域

(一)Java变量作用域

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

1、内部能访问外部

  • 代码块里能访问代码块之定义的变量

  • 代码块里不能访问代码块之定义的变量 

2、外部不能看内部 

  • 代码块里定义的变量一旦越出代码块就失效

(二)Scala变量作用域 

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

1、内部不能访问外部

  • net.liujuan.day02包创建Example15对象

package net.liujuan.day02
object Example15 {
  def main(args: Array[String]): Unit = {
    val message = "欢迎访问醉美泸州~"
    if (true) {
      println(message)
    }
  }
}
  •  运行程序,查看结果

2、外部不能访问内部

  • net.liujuan.day02包创建Example16对象 

八、补充案例

任务:评定成绩等级 

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

net.liujuan.day02包里创建Example17对象

package net.liujuan.day02
import scala.io.StdIn
object Example17 {
  def main(args: Array[String]): Unit = {
    print("score = ")
    val score = StdIn.readLine().toInt

    val comment = if (score > 100) {
      "超出范围"
    } else if (score >= 90) {
      "优秀"
    } else if (score >= 80) {
      "良好"
    } else if (score >= 70) {
      "中等"
    } else if (score >= 60) {
      "及格"
    } else if (score >= 0) {
      "不及格"
    } else {
      "超出范围"
    }

    println("评语:" + comment)
  }
}
  • 运行程序,查看结果

2、函数式风格的程序有几个特点

  • if结构像函数一样有返回值
  • if结构里除了传入参数score之外,没有别的变量。
  • -if结构里没有与外界交流,比如输入或输出或网络连接或读取文件之类。
  • 函数式编程是为了处理计算,不考虑系统的读写(I/O)。
  • 函数式编程强调没有副作用(指的是函数内部与外部互动,产生运算以外的其它结果)。函数要求独立,只返回一个值,没有其它行为,尤其不能修改外部变量的值。 

3、非函数式风格的程序

  • 看看下面这个程序 - Example18

package net.liujuan.day02
import scala.io.StdIn
object Example18 {
  def main(args: Array[String]): Unit = {
    print("score = ")
    val score = StdIn.readLine().toInt

    var comment = ""
    if (score > 100) {
      comment = "超出范围"
    } else if (score >= 90) {
      comment = "优秀"
    } else if (score >= 80) {
      comment = "良好"
    } else if (score >= 70) {
      comment = "中等"
    } else if (score >= 60) {
      comment = "及格"
    } else if (score >= 0) {
      comment = "不及格"
    } else {
      comment = "超出范围"
    }

    println("评语:" + comment)
  }
}
  • 虽然处理结果跟上面那个程序一样,但是并不符合函数式编程风格。因为if结构有副作用,修改了if结构之外的变量comment的值。

  • 再看看下面这个程序 - Example19

package net.liujuan.day02
import scala.io.StdIn
object Example19 {
  def main(args: Array[String]): Unit = {
    print("score = ")
    val score = StdIn.readLine().toInt

    if (score > 100) {
      println("评语:超出范围")
    } else if (score >= 90) {
      println("评语:优秀")
    } else if (score >= 80) {
      println("评语:良好")
    } else if (score >= 70) {
      println("评语:中等")
    } else if (score >= 60) {
      println("评语:及格")
    } else if (score >= 0) {
      println("评语:不及格")
    } else {
      println("评语:超出范围")
    }
  }
}
  • 不符合函数式编程风格。因为if结构有副作用,有写操作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值