大数据——Scala的分支控制及模式匹配

目录

一、分支控制if-else

1.1 单分支

1.2 双分支

1.3 多分支

二、嵌套分支

三、模式匹配

3.1 基本语法

3.2 if模式守卫

3.3 正则模式守卫

3.4 类型模式守卫

3.5 匹配数组

3.6 匹配列表

3.7 匹配元组

3.8 匹配对象及样例类

3.9 变量声明中的模式匹配

3.10 for表达式中的模式匹配


一、分支控制if-else

1.1 单分支

1.1.1 基本语法

        当条件表达式为true时,执行{}中的代码块

if(条件表达式){
    执行代码块
}

1.1.2 案例

        输入人的年龄,如果该同志的年龄小于 18 岁,则输出“童年”
import scala.io.StdIn

object TestIf {
  def main(args: Array[String]): Unit = {
    println("input age:")
    val age = StdIn.readInt()
    if(age<18){
      println("童年")
    }
  }
}

1.2 双分支

1.2.1 基本语法

if(条件表达式){
    执行代码块1
}else{
    执行代码块2
}

1.2.2 案例

        输入年龄,如果年龄小于 18 岁,则输出“童年”。否则,输出“成年”。
import scala.io.StdIn

object TestIfElse {
  def main(args: Array[String]): Unit = {
    println("input age:")
    val age = StdIn.readInt()
    if(age<18){
      println("童年")
    }else{
      println("成年")
    }
  }
}

1.3 多分支

1.3.1 基本语法

if(条件表达式1){
    执行代码块1
}else if(条件表达式2){
    执行代码块2
}
...
else{
    执行代码块n
}

1.3.2 案例

        输入年龄,如果年龄小于 18 岁,则输出“童年”。如果年龄大于等于 18 且小于等于 30 ,则输出 中年 ,否则,输出“老年”。
import scala.io.StdIn

object TestIfElse {
  def main(args: Array[String]): Unit = {
    println("input age:")
    val age = StdIn.readInt()
    if(age<18){
      println("童年")
    }else if(age>=18 && age<30){
      println("中年")
    }else{
      println("老年")
    }
  }
}

注意

        1.Scala 中 if else 表达式其实是有返回值的,具体返回值取决于满足条件的代码体的最后一行内容。

import scala.io.StdIn

object TestIfElse {
  def main(args: Array[String]): Unit = {
    println("input age")
    var age = StdIn.readInt()
    val res :String = if (age < 18){
      "童年"
    }else if(age>=18 && age<30){
      "中年"
    }else{
      "老年"
    }
    println(res)
  }
}

        2.Scala 中返回值类型不一致,取它们共同的祖先类型。


import scala.io.StdIn

object TestIfElse {
  def main(args: Array[String]): Unit = {
    println("input age")
    var age = StdIn.readInt()
    val res:Any = if (age < 18){
      "童年"
    }else if(age>=18 && age<30){
      "中年"
    }else{
      100
    }
    println(res)
  }
}

        3.Java 中的三元运算符可以用 if else 实现                

                如果大括号{}内的逻辑代码只有一行,大括号可以省略。如果省略大括号, if 只对最近
        的一行逻辑代码起作用。
import scala.io.StdIn

object TestIfElse {
  def main(args: Array[String]): Unit = {
    println("input age")
    var age = StdIn.readInt()
    //省略大括号只对最近的一句代码起作用
    val res:Any = if (age < 18) "童年" else "成年" "不起作用"
    println(res)
  }
}

二、嵌套分支

        在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支的结构称为内层。分支外面的分支结构称为外层分支。嵌套分支不要超过 3 层。
2.1 基本语法
if(条件表达式1){
    if(条件表达式2){
        代码块
    }else{
        代码块
    }
}

2.2 案例

        如果输入的年龄小于 18 ,返回 童年 。如果输入的年龄大于等于 18 ,需要再判断:如果年龄大于等于 18 且小于 30 ,返回 中年 ;如果其他,返回 老年
import scala.io.StdIn

object TestIfElse {
  def main(args: Array[String]): Unit = {
    print("input age:\t")
    var age = StdIn.readInt()
    val result = if(age<18){
      "童年"
    }else{
      if(age<30){
        "中年"
      }else{
        "老年"
      }
    }
    println(result)
  }
}

三、模式匹配

Scala 中的模式匹配 类似于 Java 中的 switch 语法

3.1 基本语法

3.1.1 模式匹配语法中,采用match 关键字声明,每个分支采用 case 关键字进行声明,当需要匹配时,会从第一个 case分支开始,如果匹配成功,那么执行对应的逻辑代码,如果匹配不成功,继续执行下一个分支进行判断。如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java default 语句。
import scala.io.StdIn

object TestMatchCase {
  def main(args: Array[String]): Unit = {
    print("请输入你需要的服务号:\t")
    val dial = StdIn.readInt()
    val result = dial match {
      case 1=>"充值"
      case 2=>"话费查询"
      case 3=>"人工服务"
      case _=>"无此服务"
    }
    println(result)
  }
}

3.1.2 说明

(1)如果所有 case 都不匹配,那么会执行 case _ 分支,类似于 Java 中 default 语句,若此时没有 case _ 分支,那么会抛出 MatchError。
(2)每个 case 中,不需要使用 break 语句,自动中断 case。
(3)match case 语句可以匹配任何类型,而不只是字面量。
(4)=> 后面的代码块,直到下一个 case 语句之前的代码是作为一个整体执行,可以
使用{}括起来,也可以不括

3.2 if模式守卫

3.2.1 说明

        如果想要表达匹配某个范围的数据,就需要在模式匹配中增加条件守卫。

3.2.2 案例

        当成绩大于等于90时等级为A,成绩大等于于80时等级为B,成绩大于等于60时等级为C,成绩低于60时等级为D

import scala.io.StdIn

object TestMatchCase {
  def main(args: Array[String]): Unit = {
    print("请输入成绩:\t")
    val score = StdIn.readInt()
    val result = score match {
      case _ if(score >= 90) => "A"
      case _ if(score >= 80) => "B"
      case _ if(score >= 60) => "C"
      case _ => "D"
    }
    println(result)
  }
}

3.3 正则模式守卫

3.3.1 说明

        如果想要表达匹配某个正则表达式,就需要在模式匹配中增加正则守卫。

3.3.2 案例

        判断输入的字符串是邮箱、手机号还是身份证号

import scala.io.StdIn

object TestMatchCase {
  def main(args: Array[String]): Unit = {
    print("请输入字符串:\t")
    val value = StdIn.readLine()
    val rMail = "\\w+@\\w{2,}\\.(com|cn|org|net)".r
    val rPhone = "(1)[3-9]\\d{9}".r
    val rPid = "\\d{17}(\\d|X)".r
    val result = value match {
      case rMail(value) => "MAIL"
      case rPhone(value) => "PHONE"
      case rPid(value) => "PID"
      case _ => "unknown"
    }
    println(result)
  }
}

3.4 类型模式守卫

3.4.1 说明

        需要进行类型判断时,可以使用模式守卫

3.4.2 案例

object TestMatchClass {
  def describe(x: Any) = x match {
    case i: Int => "Int"
    case s: String => "String hello"
    case m: List[_] => "List"
    case c: Array[Int] => "Array[Int]"
    case someThing => "something else " + someThing
  }
  def main(args: Array[String]): Unit = {
    //泛型擦除
    println(describe(List(1, 2, 3, 4, 5)))
    //数组例外,可保留泛型
    println(describe(Array(1, 2, 3, 4, 5, 6)))
    println(describe(Array("abc")))
  }
}

3.5 匹配数组

3.5.1 说明

        scala 模式匹配可以对集合进行精确的匹配,例如匹配只有两个元素的、且第一个元素为 0 的数组。
3.5.2 案例
object TestMatchArray {
  def main(args: Array[String]): Unit = {
    for (arr <- Array(Array(0), Array(1, 0), Array(0, 1, 0),
      Array(1, 1, 0), Array("hello", 90),Array(1, 1, 0, 1))) { //对一个数组集合进行遍历
      val result = arr match {
        case Array(0) => "0" //匹配 Array(0) 这个数组
        case Array(x, y) => x + "," + y //匹配有两个元素的数组,然后将将元素值赋给对应的 x,y
        case Array(0, _*) => "以 0 开头的数组" //匹配以 0 开头和数组
        case _ => "something else"
      }
      println("result = " + result)
    }
  }
}

3.6 匹配列表

object TestMatchList {
  def main(args: Array[String]): Unit = {
    //list 是一个存放 List 集合的数组
    for (list <- Array(List(0), List(1, 0), List(0, 0, 0), List(1,
      0, 0), List(88))) {
      val result = list match {
        case List(0) => "0" //匹配 List(0)
        case List(x, y) => x + "," + y //匹配有两个元素的 List
        case List(0, _*) => "0 ..."
        case List(x) => x
        case _ => "something else"
      }
      println(result)
    }
  }
}

3.7 匹配元组

object TestMatchTuple {
  def main(args: Array[String]): Unit = {
    //对一个元组集合进行遍历
    for (tuple <- Array((0, 1), (1, 0), (1, 1), (1, 0, 2))) {
      val result = tuple match {
        case (0, _) => "0 ..." //是第一个元素是 0 的元组
        case (y, 0) => "" + y + "0" // 匹配后一个元素是 0 的对偶元组
        case (a, b) => "" + a + " " + b
        case _ => "something else" //默认
      }
      println(result)
    }
  }
}

3.8 匹配对象及样例类

3.8.1 基本语法

class User(val name: String, val age: Int)

object User {
  def apply(name: String, age: Int): User = new User(name, age)
  def unapply(user: User): Option[(String, Int)] = {
    if (user == null)
      None
    else
      Some(user.name, user.age)
  } }
object TestMatchUnapply {
  def main(args: Array[String]): Unit = {
    val user: User = User("zhangsan", 11)
    val result = user match {
      case User("zhangsan", 11) => "yes"
      case _ => "no"
    }
    println(result)
  }
}
小结
val user = User("zhangsan",11) ,该语句在执行时,实际调用的是 User 伴生对象中的
apply 方法,因此不用 new 关键字 就能构造出相应的对象。
当将 User("zhangsan", 11) 写在 case 后时 [case User("zhangsan", 11) => "yes"] ,会默
认调用 unapply 方法 ( 对象提取器 ) user 作为 unapply 方法的参数 unapply 方法
user 对象的 name age 属性提取出来,与 User("zhangsan", 11) 中的属性值进行
匹配
case 中对象的 unapply 方法 ( 提取器 ) 返回 Some ,且所有属性均一致,才算匹配成功 ,
属性不一致,或返回 None ,则匹配失败。
若只提取对象的一个属性,则提取器为 unapply (obj:Obj): Option[ T ]
若提取对象的多个属性,则提取器为 unapply (obj:Obj): Option[ (T1,T2,T3…) ]
若提取对象的可变个属性,则提取器为 unapplySeq (obj:Obj): Option[ Seq[T] ]
3.8.2 样例类
1 )语法:
        case class Person (name: String, age: Int)
2 )说明
        1 样例类仍然是类,和普通类相比,只是其自动生成了伴生对象,并且伴生对象中 自动提供了一些常用的方法,如 apply unapply toString equals hashCode copy
        2 样例类是为模式匹配而优化的类,因为其默认提供了 unapply 方法,因此,样例 类可以直接使用模式匹配,而无需自己实现 unapply 方法。
        3 构造器中的每一个参数都成为 val ,除非它被显式地声明为 var (不建议这样做)
3 )实操
        上述匹配对象的案例使用样例类会节省大量代码
case class User(name: String, age: Int)
object TestMatchUnapply {
 def main(args: Array[String]): Unit = {
 val user: User = User("zhangsan", 11)
 val result = user match {
 case User("zhangsan", 11) => "yes"
 case _ => "no"
 }
 println(result)
 } }

3.9 变量声明中的模式匹配

case class Person(name: String, age: Int)
object TestMatchVariable {
 def main(args: Array[String]): Unit = {
 val (x, y) = (1, 2)
 println(s"x=$x,y=$y")
 val Array(first, second, _*) = Array(1, 7, 2, 9)
 println(s"first=$first,second=$second")
 val Person(name, age) = Person1("zhangsan", 16)
 println(s"name=$name,age=$age")
 } }

3.10 for表达式中的模式匹配

object TestMatchFor {
  def main(args: Array[String]): Unit = {
    val map = Map("A" -> 1, "B" -> 0, "C" -> 3)
    for ((k, v) <- map) { //直接将 map 中的 k-v 遍历出来
      println(k + " -> " + v) //3 个
    }
    println("----------------------")
    //遍历 value=0 的 k-v ,如果 v 不是 0,过滤
    for ((k, 0) <- map) {
      println(k + " --> " + 0) // B->0
    }
    println("----------------------")
    //if v == 0 是一个过滤的条件
    for ((k, v) <- map if v >= 1) {
      println(k + " ---> " + v) // A->1 和 c->33
    }
  }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vicky_Tang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值