53_模式匹配
/*
* 语法
* 目标值 match {
* case 条件1 => 操作1
* case 条件2 => 操作2
* case 条件3 => 操作3
* case 条件4 => 操作4
* case _ => 操作5
* }
* 返回值 操作对应的结果
* 说明
* 1.都匹配不上时,会进入_分支,如果没有_分支,会报错MatchError
* 2.每个case分支中,不需要使用break,在满足的条件分支下停止,不会有穿透
* 3.目标值可以匹配任何类型,不只是字面量
* 4.=>后面是代码块,可以使用 {}
*
* 模式守卫
* 匹配范围,match的case语句中可以定义变量
*
* 通配符
* 1. _ 单元素通配符 / else通配符
* 2. _* 多元素通配符
* 3. x,y(任意变量名称) 单元素通配符
*
* 匹配类型
* 1. 匹配常量 常量类型可以是 字符串、字符、数字、布尔值等
* 2. 匹配数据类型
* 说明
* 1. 判断变量类型 可以使用 obj.isInstanceOf[dataType]
* 泛型擦除
* 泛型只在编译器有效,运行期会去掉(数组除外)
* 3. 匹配数组
* 判断数组元素个数、及数组元素的值
* 4. 匹配列表
* 判断啥样类型Array
* 5. 匹配元组
* 扩展使用
* 1. 为多个变量赋值
* 2. for推导式中使用变量
* 6. 匹配对象
* 必须实现unapply方法
*
* 样例类
* 语法
* case class ClassName
* 作用
* 默认实现 伴生类及 apply和unapply方法
* 类参数默认为 类成员属性
*
* */
/* * 语法 * 目标值 match { * case 条件1 => 操作1 * case 条件2 => 操作2 * case 条件3 => 操作3 * case 条件4 => 操作4 * case _ => 操作5 * } * 返回值 操作对应的结果 * 说明 * 1.都匹配不上时,会进入_分支,如果没有_分支,会报错MatchError * 2.每个case分支中,不需要使用break,在满足的条件分支下停止,不会有穿透 * 3.目标值可以匹配任何类型,不只是字面量 * 4.=>后面是代码块,可以使用 {} * * 模式守卫 * 匹配范围,match的case语句中可以定义变量 * * 通配符 * 1. _ 单元素通配符 / else通配符 * 2. _* 多元素通配符 * 3. x,y(任意变量名称) 单元素通配符 * * 匹配类型 * 1. 匹配常量 常量类型可以是 字符串、字符、数字、布尔值等 * 2. 匹配数据类型 * 说明 * 1. 判断变量类型 可以使用 obj.isInstanceOf[dataType] * 泛型擦除 * 泛型只在编译器有效,运行期会去掉(数组除外) * 3. 匹配数组 * 判断数组元素个数、及数组元素的值 * 4. 匹配列表 * 判断啥样类型Array * 5. 匹配元组 * 扩展使用 * 1. 为多个变量赋值 * 2. for推导式中使用变量 * 6. 匹配对象 * 必须实现unapply方法 * * 样例类 * 语法 * case class ClassName * 作用 * 默认实现 伴生类及 apply和unapply方法 * 类参数默认为 类成员属性 * * */ //基础语法 object MatchTest extends App { var a = 3 var b = 2 var op = '.' var result = op match { case '+' => a + b case '-' => a - b case '*' => a * b case '/' => a / b case _ => "非法操作符" } println(result) } //模式守卫 object MatchIf extends App { //模式守卫 //会把目标值x 赋值给i def abs(x: Int) = { x match { case i: Int if i >= 0 => i case a: Int if a < 0 => -a case _ => "非法目标值" } } println(abs(-10)) } //匹配字面量 object MatchConst extends App { //匹配常量 def desc(x: Any) = x match { case 'x' => println(x.getClass) case "str" => println(x.getClass) case 1 => println(x.getClass) case 1.1 => println(x.getClass) case _ => println(x.getClass) } desc(1) } //匹配数据类型 + 泛型擦除 object MatchDataType extends App { //匹配类型 var list: List[Int] = List(1, 2, 3, 4, 5, 6) var arr: Array[Int] = Array(1, 2, 3, 4, 5, 6) var str = "字符串" //判断数据类型 println(list.isInstanceOf[List[String]]) //判断变量类型 println(arr.isInstanceOf[Array[String]]) //判断变量类型 def showDataType(data: Any) = data match { case i: Int => println("Int") case s: String => println("String") case l: List[String] => println("List[Int]") case a: Array[Int] => println("Array[Int]") case other => println("other") } showDataType(list) //运行期间会将list的泛型擦除的,不会判断list的泛型 } //匹配数组 object MatchArray extends App { //初始化 var arr = Array( Array(0), Array(1), Array(3) , Array(1, 2), Array(2, 3), Array(4, 5) , Array(1, 2, 3) , Array("dawang", 90) ) //遍历 for (e <- arr) { var result = e match { case Array(0) => "等于Array(0)" // 匹配Array(0) case Array(x, y) => s"${x} : ${y}" //匹配Array(x,y) case Array(0, _*) => "0开头的数组" case _ => "other" } println(result) } } //匹配链表 object MatchList extends App { //初始化 var list = List( List(0), List(1), List(2) , List(1, 2) , List(1, 2, 3) , List(1, "大王", 3) ) //遍历 for (e <- list) { //match每个元素e var result = e match { case List(x) => "match只有一个元素的list" case List(1, 2) => "match-List(1, 2)的list" case List(_, _, _) => "match-三个元素的list" case _ => "other" } println(result) } println("==================") //方式二 var list2 = List(1, 2, 3, 4, 5) list2 match { case first :: second :: rest => println(s"${first} - ${second} -${rest}") case _ => println("其他") } } //匹配元组 object MatchTuple extends App { //初始化 var tuple = Array( (0, 1), (1, 2, 3), (2, 2, 1), (2, 2, 2), (1, 2, 3, 4), (2, 2) ) //遍历 for (e <- tuple) { var result = e match { case (_, _) => "二元元组" case (_, _, _) => "三元元组" case (_, _, _, _) => "四元元组" case _ => "other" } println(result) } } //为多个变量赋值 object MatchMultiVal extends App { //1. 声明多个变量(使用元组) var (x, y) = (10, "大王") println(s"${x} - ${y}") //2. 声明多个变量(使用链表) var List(id, name, age) = List(1, "黎明", 20) println(s"${id} - ${name} - ${age}") //3. 声明多个变量(使用链表2) var f1 :: f2 :: f3 = List(1, 2, 3, 4, 5) println(s"${f1} - ${f2} - ${f3}") } //for推导式中使用变量 object MatchForVal extends App { //初始化list var list = List(("word", 2), ("key", 3), ("word", 4), ("dawang", 2), ("reduce", 2), ("word", 2)) //1.普通遍历 for (e <- list) { println(s"${e._1} - ${e._2}") } println("==============") //2.接收变量为元组 for ((word, key) <- list) { println(s"${word} - ${key}") } println("==========") //3.接收变量为元组,且指定某个位置的值 for (("word", key) <- list) { println(s"word - ${key}") } } //匹配对象 object MatchObject extends App { //创建 Person实例 var per = new Person(18, "dawang") //判断 实例属性值 per match { case Person(19, "dawang") => println("这个是") case _ => println("这不是") } //创建样例类实例 var std = Student(1, "张") //模式匹配(证明李明是不是李明) std match { case Student(1, "李明") => println("这是李明") case Student(1, "张三") => println("这是张三") case _ => println("这不是张三也不是李明") } } object Person { def apply(age: Int, name: String): Person = new Person(age, name) def unapply(per: Person): Option[(Int, String)] = { if (per == null) None else Some(per.age, per.name) } } class Person(var age: Int, var name: String) //定义样例类 case class Student(id: Int, name: String)
示例
// 案例3 : 将 List(List(1,2),3,List(4,5)) 打散 object flatMapWithListTest extends App { //1. 获取配置文件,及上下文对象 private val sparkConf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("spark") private val sparkContext = new SparkContext(sparkConf) //2. 获取rdd private val rdd = sparkContext.makeRDD(List( List(1, 2) , 3 , List(4, 5, 5, 7, 9) , List(4, 5)), 1) // 添加转换因子 // 传入的参数的返回值 必须是可迭代的对象 // private val rdd2 = rdd.flatMap( // e => { // e match { // case list: List[_] => list // case i: Int => List(i) // } // } // ) //极简原则 private val rdd2 = rdd.flatMap { case list: List[_] => list case i: Int => List(i) } println(rdd2.collect().mkString(",")) //3. 关闭资源 sparkContext.stop }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界