Scala中的模式匹配【简单模式匹配,匹配类型,守卫,匹配样例累、匹配集合、变量申明中的模式匹配、匹配for1表达式】


模式匹配 match

Scala中有一个非常强大的匹配机制,例如:

  • 判断固定值
  • 类型查询
  • 快速获取数据

简单模式匹配

一个模式匹配包含了一系列备选项,每个备选项都开始于关键字 case ,而且每个备选项都包含一个模式及一到多个表达式。箭头符号=>隔开了模式和表达式。


格式:

变量 match {
	case "常量1" => 表达式1
	case "常量2" => 表达式2
	case "常量3" => 表达式3
	case _ => 表达式4		//默认匹配项
}

执行流程:

  • 1.先执行第一个case,看变量值该case对应的常量值是否一致。
  • 2.如果一致,则执行该case对应的表达式。
  • 3.如果不一致,则往后执行下一个case,看变量值该case对应的常量值是否一致。
  • 4.以此类推,如果所有的case都不匹配,则执行case_对应的表达式。

案例需求:

  • 1.提示用户录入一个单词并接受。
  • 2.判断该单词是否能够匹配一下单词,如果能匹配,返回一句话。
  • 3.打印结果。
单词 返回
hadoop 大数据分布式存储和计算框架
zookeeper 大数据分布式协调服务矿建
spark 大数据分布式内存计算框架
未匹配 未匹配
import scala.io.StdIn

object 简单模式匹配 {
    
    

  def main(args: Array[String]): Unit = {
    
    
    //1.提示用户录入字符串并接受
    println("请录入一个字符串:")
    var str = StdIn.readLine()

    //2.判断字符串是否是指定的内容,并接受结果
    val result = str match {
    
    
      case "hadoop" => "大数据分布式存储和计算框架"
      case "zookeeper" => "大数据分布式协调服务框架"
      case "spark" => "大数据分布式内存计算框架"
      case _ => "未匹配"
    }

    //3.打印结果
    println(result)
    println("-" * 15) //分割线

    //简写形式
    str match {
    
    
      case "hadoop" => println("大数据分布式存储和计算框架")
      case "zookeeper" => println("大数据分布式协调服务框架")
      case "spark" => println("大数据分布式内存计算框架")
      case _ => println("未匹配")
    }
  }

}
请录入一个字符串:
spark
大数据分布式内存计算框架
---------------
大数据分布式内存计算框架

Process finished with exit code 0

匹配类型

除了匹配数据之外, match表达式还可以进行类型匹配。如果我们要根据不同的数据类型,来执行不同的逻辑,也可以使用match表达式来实现。

格式:

对象名 match { 
	case 变量名1: 类型1 => 表达式1 
	case 变量名2: 类型2 => 表达式2 
	case 	变量名3: 类型3 => 表达式3 
	... 
	case _ => 表达式4 
}

注意: 如果case表达式中无需使用到匹配到的变量,可以使用下划线代替。

案例需求:

  1. 定义一个变量为Any类型,然后分别给其赋值为"hadoop"、1、1.0
  2. 定义模式匹配,然后分别打印类型的名称

代码演示:

object 匹配类型 {
    
    

  def main(args: Array[String]): Unit = {
    
    
    //1.定义一个变量为Any类型,然后分别给其赋值为 "hadoop"、1、1.0
    val a:Any = 1.0
    //2.定义模式匹配,然后分别打印类型的名称
    val result = a match {
    
    
      case x:String => s"${x} 是String类型数据"
      case x:Double => s"${x} 是Double类型数据"
      case x:Int => s"${x} 是Int类型数据"
      case _ => "未匹配"
    }
    //3.打印结果
    println(result)

    //4.优化版,如果在case校验的时候,变量没有被使用,则可以用_替代
    val result2 = a match {
    
    
      case _:String => "String"
      case _:Double => "Double"
      case _:Int => "Int"
      case _ => "未匹配"
    }
    println(result2)
  }

}
1.0Double类型数据
Double

Process finished with exit code 0

守卫

所谓的守卫指的是,在 case 语句中添加 if 条件判断,这样可以让我们的代码更加简洁。

格式:

变量 match { 
	case 变量名 if条件1 => 表达式1 
	case 变量名 if条件2 => 表达式2 
	case 变量名 if条件3 => 表达式3 
	... 
	case _ => 表达式4 
}

案例需求:

  1. 从控制台读入一个数字a(使用StdIn.readInt)
  2. 如果 a >= 0 而且 a <= 3,打印[0-3]
  3. 如果 a >= 4 而且 a <= 8,打印[4,8]
  4. 否则,打印未匹配

代码演示:

import scala.io.StdIn

object 守卫 {
    
    

  def main(args: Array[String]): Unit = {
    
    
    //1.从控制台读入一个数字a(使用StdIn.readInt)
    println("请录入一个数字:")
    var num = StdIn.readInt()
    //2.模式匹配
    num match {
    
    
      //2.1 如果 a >= 0 而且 a <= 3,打印[0-3]
      case a if a >= 0 && a <= 3 => println("[0-3]")
      //2.2 如果 a >= 4 而且 a <= 8,打印[4,8]
      case a if a >= 4 && a <= 8 => println("[4-8]")
      //2.3 否则,打印未匹配
      case _ => println("未匹配")
    }
  }

}
请录入一个数字:
4
[4-8]

Process finished with exit code 0

匹配样例类

Scala中可以使用模式匹配来匹配样例类,从而实现可以快速获取样例类中的成员数据。

格式:

对象名 match { 
	case 样例类型1(字段1, 字段2, 字段n) => 表达式1 
	case 样例类型2(字段1, 字段2, 字段n) => 表达式2 
	case 样例类型3(字段1, 字段2, 字段n) => 表达式3 
	... 
	case _ => 表达式4 
}

注意:

  1. 样例类型后的小括号中, 编写的字段个数要和该样例类的字段个数保持一致.
  2. 通过match进行模式匹配的时候, 要匹配的对象必须声明为: Any类型.

案例需求:

  1. 创建两个样例类Customer(包含姓名, 年龄字段), Order(包含id字段)
  2. 分别定义两个样例类的对象,并指定为Any类型
  3. 使用模式匹配这两个对象,并分别打印它们的成员变量值

代码演示:

object 匹配样例类 {
    
    

  //1. 创建俩个样例类Customer、Order
  //1.1 Customer包含姓名、年龄字段
  case class Customer(var name: String, var age: Int)
  //1.2 Order包含id字段
  case class Order(id: Int)

  def main(args: Array[String]): Unit = {
    
    
    //2. 分别定义俩个案例类的对象,并指定为Any类型
    val c: Any = Customer("糖糖", 73)
    val o: Any = Order(123)
    val arr: Any = Array(0, 1)

    //3. 使用模式匹配这俩个对象,并且分别打印它们的成员变量值
    c match {
    
    
      case Customer(a, b) => println(s"Customer类型的对象,name${a}, age=${b}")
      case Order(c) => println(s"Order类型,id=${c}")
      case _ => println("未匹配")
    }
  }

}
Customer类型的对象,name糖糖, age=73

Process finished with exit code 0

匹配集合

除了上述功能之外,Scala中的模式匹配,还能用来匹配数组,元组,集合(列表,集,映射)等。

1. 匹配数组

需求:

  1. 依次修改代码定义以下三个数组

  2. 使用模式匹配, 匹配上述数组.

    Array(1,x,y) // 以1开头,后续的两个元素不固定
    Array(0) // 只匹配一个0元素的元素
    Array(0, …) // 可以任意数量,但是以0开头

代码演示:

object 匹配数组 {
    
    

  def main(args: Array[String]): Unit = {
    
    
    //1. 定义三个数组
    val arr1 = Array(1, 2, 3)
    val arr2 = Array(0)
    val arr3 = Array(1, 2, 3, 4, 5)
    //2. 通过模式匹配,找到指定的数组
    arr1 match {
    
    
      //匹配:长度为3,首元素为1,后面俩个元素无所谓
      case Array(1, x, y) => println(s"匹配长度为3,首元素为1,后俩个元素为:${x},${y}")
      //匹配:只有一个0元素的数组
      case Array(0) => println("匹配:只有一个0元素的数组")
      //匹配:第一个元素是1,后面元素后面元素随便的数组
      case Array(1, _*) => println("匹配:第一个元素是1,后面元素后面元素随便的数组")
      //其它校验项
      case _ => println("未匹配")
    }
  }

}
匹配长度为3,首元素为1,后俩个元素为:23

Process finished with exit code 0

2. 匹配列表

  1. 依次修改代码定义以下三个列表

  2. 使用模式匹配, 匹配上述列表

    List(0) // 只保存0一个元素的列表
    List(0,…) // 以0开头的列表,数量不固定
    List(x,y) // 只包含两个元素的列表

代码演示:

object 匹配列表 {
    
    

  def main(args: Array[String]): Unit = {
    
    
    //1. 定义列表
    var list1 = List(0)
    var list2 = List(0, 1, 2, 3, 4, 5)
    var list3 = List(1, 2)

    //2. 通过match进行模式匹配
    //思路一:通过List()来实现
    list1 match {
    
    
      case List(0) => println("匹配:只有一个0元素的列表")
      case List(0, _*) => println("匹配:0开头,后面元素随便的列表")
      case List(x, y) => println(s"匹配:只有俩个元素的列表:${x}, ${y}")
      case _ => println("未匹配")
    }

    //思路二:采用关键字优化 Nil,tail
    list2 match {
    
    
      case 0 :: Nil => println("匹配:只有一个0元素的列表")
      case 0 :: tail => println("匹配:0开头,后面元素随便的列表")
      case x :: y :: Nil => println(s"匹配:只有俩个元素的列表,元素为:${x}, ${y}")
      case _ => println("未匹配")
    }
  }

}
匹配:只有一个0元素的列表
匹配:0开头,后面元素随便的列表

Process finished with exit code 0

3. 匹配元组

需求:

  1. 依次修改代码定义以下两个元组
  2. 使用模式匹配, 匹配上述元组

(1, x, y) // 以1开头的、一共三个元素的元组
(x, y, 5) // 一共有三个元素,最后一个元素为5的元组

参考代码:

object 匹配元组 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //1. 定义俩个元组
    val a = (1, 2, 3)
    val b = (3, 4, 5)
    val c = (3, 4)

    //2. 通过模式匹配,匹配指定元素
    a match {
    
    
      case (1, x, y) => println(s"匹配:长度为3,以1开头,后俩个元素无所谓的元组,这里后俩个元素是:${x},${y}")
      case (x, y, 5) => println(s"匹配:长度为3,以5结尾,前俩个元素无所谓的元组,这里前俩个元素是:${x},${y}")
      case _ => println("未匹配")
    }
  }
}
匹配:长度为3,以1开头,后俩个元素无所谓的元组,这里后俩个元素是:23

Process finished with exit code 0

变量申明中的模式匹配

在定义变量时,可以使用模式匹配快速获取数据. 例如: 快速从数组,列表中获取数据 .

案例需求:

  1. 生成包含0-10数字的数组,使用模式匹配分别获取第二个、第三个、第四个元素
  2. 生成包含0-10数字的列表,使用模式匹配分别获取第一个、第二个元素

参考代码

object 变量申明中的模式匹配 {
    
    

  def main(args: Array[String]): Unit = {
    
    
    //1. 生成包含0-10数字的数组,使用模式匹配分别获取第二个、第三个、第四个元素
    //1.1 生成包含0-10数字的数组
    val arr = (0 to 10).toArray
    //1.2 使用模式匹配分别获取第二个、第三个、第四个元素
    val Array(_, x, y, z, _*) = arr
    //1.3 打印结果
    println(x, y, z)
    println("-" * 15)

    //2. 生成包含0-10数字的列表,使用模式匹配分别获取第一个,第二个元素
    //2.1 生成包含0-10数字的列表
    val list = (0 to 10).toList
    //2.2 使用模式匹配分别获取第一个第二个元素
    //思路一: ::, List() 实现
    val List(a, b, _*) = list
    //思路二: ::, tail 实现
    val c :: d :: tail = list
    //2.3 打印结果
    println(a, b)
    println(c, d)
  }

}
(1,2,3)
---------------
(0,1)
(0,1)

Process finished with exit code 0

匹配for表达式

Scala中还可以使用模式匹配来匹配for表达式,从而实现快速获取指定数据, 让我们的代码看起来更简洁, 更优雅.

案例需求:

  1. 定义变量记录学生的姓名和年龄, 例如: “张三” -> 23, “李四” -> 24, “王五” -> 23, “赵六” -> 26
  2. 获取所有年龄为23的学生信息, 并打印结果

参考代码:

object 匹配for表达式 {
    
    

  def main(args: Array[String]): Unit = {
    
    
    //1. 定义变量记录学生的姓名和年龄
    val map1 = Map("张三" -> 23, "李四" -> 24, "王五" -> 23, "赵六" -> 26)
    //2. 获取所有年龄为23的学生信息
    //2.1 格式一:通过if语句实现
    for((k, v) <- map1 if v == 23) println(s"${k} = ${v}")

    println("-" * 20)

    //2.2 格式二:通过固定值实现
    for ((k, 23) <- map1) println(k + " = 23")
  }

}
张三 = 23
王五 = 23
--------------------
张三 = 23
王五 = 23

Process finished with exit code 0

猜你喜欢

转载自blog.csdn.net/shuyv/article/details/121066738
今日推荐