网站要咋建立,网站开发的广告词,网站建设与制作设计公司,东莞网站制作公司报价1.模式匹配
Scala中有一个非常强大的模式匹配机制#xff0c;应用也非常广泛, 例如:
判断固定值类型查询快速获取数据
1.1 简单模式匹配
一个模式匹配包含了一系列备选项#xff0c;每个备选项都开始于关键字 case。且每个备选项都包含了一个模式及一到多
个表达式。箭头…1.模式匹配
Scala中有一个非常强大的模式匹配机制应用也非常广泛, 例如:
判断固定值类型查询快速获取数据
1.1 简单模式匹配
一个模式匹配包含了一系列备选项每个备选项都开始于关键字 case。且每个备选项都包含了一个模式及一到多
个表达式。箭头符号 隔开了模式和表达式。
格式
变量 match {
case 常量1 表达式1
case 常量2 表达式2
case 常量3 表达式3
case _ 表达式4 // 默认匹配项
}执行流程
先执行第一个case, 看 变量值 和 该case对应的常量值 是否一致.如果一致, 则执行该case对应的表达式.如果不一致, 则往后执行下一个case, 看 变量值 和 该case对应的常量值 是否一致.以此类推, 如果所有的case都不匹配, 则执行 case _ 对应的表达式.
需求
提示用户录入一个单词并接收.判断该单词是否能够匹配以下单词如果能匹配返回一句话打印结果.
单词返回hadoop大数据分布式存储和计算框架zookeeper大数据分布式协调服务框架spark大数据分布式内存计算框架未匹配未匹配
参考代码
import scala.io.StdIn
//案例: 模式匹配之简单匹配
object ClassDemo01 {
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(未匹配)
}
}
}1.2 匹配类型
除了匹配数据之外, match表达式还可以进行类型匹配。如果我们要根据不同的数据类型来执行不同的逻辑也可以使用match表达式来实现。
格式
对象名 match {
case 变量名1: 类型1 表达式1
case 变量名2: 类型2 表达式2
case 变量名3: 类型3 表达式3
...
case _ 表达式4
}注意: 如果case表达式中无需使用到匹配到的变量可以使用下划线代代
需求
定义一个变量为Any类型然后分别给其赋值为hadoop、1、1.0定义模式匹配然后分别打印类型的名称
参考代码
//案例: 模式匹配之匹配类型
object ClassDemo02 {
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.3 守卫
所谓的守卫指的是 在case语句中添加if条件判断 , 这样可以让我们的代码更简洁, 更优雅.
格式
变量 match {
case 变量名 if条件1 表达式1
case 变量名 if条件2 表达式2
case 变量名 if条件3 表达式3
...
case _ 表达式4
}需求
从控制台读入一个数字a使用StdIn.readInt如果 a 0 而且 a 3打印[0-3]如果 a 4 而且 a 8打印[4,8]否则打印未匹配
参考代码
//案例: 模式匹配之守卫
object ClassDemo03 {
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(未匹配)
}
}
}1.4 匹配样例类
Scala中可以使用模式匹配来匹配样例类从而实现可以快速获取样例类中的成员数据。后续我们在开发Akka案
例时还会经常用到。
格式
对象名 match {
case 样例类型1(字段1, 字段2, 字段n) 表达式1
case 样例类型2(字段1, 字段2, 字段n) 表达式2
case 样例类型3(字段1, 字段2, 字段n) 表达式3
...
case _ 表达式4
}样例类型后的小括号中, 编写的字段个数要和该样例类的字段个数保持一致. 通过match进行模式匹配的时候, 要匹配的对象必须声明为: Any类型.
需求
创建两个样例类Customer(包含姓名, 年龄字段), Order(包含id字段)分别定义两个样例类的对象并指定为Any类型使用模式匹配这两个对象并分别打印它们的成员变量值
参考代码
//案例: 模式匹配之匹配样例类
object ClassDemo04 {
//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(sCustomer类型的对象, name${a}, age${b})
case Order(c) println(sOrder类型, id${c})
case _ println(未匹配)
}
}
}1.5 匹配集合
除了上述功能之外, Scala中的模式匹配还能用来匹配数组, 元组, 集合(列表, 集, 映射)等。
1.5.1 示例一: 匹配数组
需求
依次修改代码定义以下三个数
Array(1,x,y) // 以1开头后续的两个元素不固定
Array(0) // 只匹配一个0元素的元素
Array(0, ...) // 可以任意数量但是以0开头使用模式匹配, 匹配上述数组.
参考代码
//案例: 模式匹配之匹配数组
object ClassDemo05 {
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. 通过模式匹配, 找到指定的数组.
arr2 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(未匹配)
}
}
}1.5.2 示例二匹配列表
需求
依次修改代码定义以下三个列表
List(0) // 只保存0一个元素的列表
List(0,...) // 以0开头的列表数量不固定
List(x,y) // 只包含两个元素的列表使用模式匹配, 匹配上述列表.
参考代码
//案例: 模式匹配之匹配列表
object ClassDemo06 {
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
list1 match {
case 0 :: Nil println(匹配: 只有一个0元素的列表)
case 0 :: tail println(匹配: 0开头, 后边元素无所谓的列表)
case x :: y :: Nil println(s匹配: 只有两个元素的列表, 元素为: ${x}, ${y})
case _ println(未匹配)
}
}
}1.5.3 案例三:匹配元组
需求
依次修改代码定义以下两个元组
(1, x, y) // 以1开头的、一共三个元素的元组
(x, y, 5) // 一共有三个元素最后一个元素为5的元组使用模式匹配, 匹配上述元组.
参考代码
//案例: 模式匹配之匹配元组
object ClassDemo07 {
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(未匹配)
}
}
}1.6 变量声明中的模式匹配
在定义变量时可以使用模式匹配快速获取数据. 例如: 快速从数组,列表中获取数据 .
需求 生成包含0-10数字的数组使用模式匹配分别获取第二个、第三个、第四个元素 生成包含0-10数字的列表使用模式匹配分别获取第一个、第二个元素
参考代码
//案例: 演示变量声明中的模式匹配.
object ClassDemo08 {
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.7 匹配for表达式
Scala中还可以使用模式匹配来匹配for表达式从而实现快速获取指定数据, 让我们的代码看起来更简洁, 更优雅.
需求
定义变量记录学生的姓名和年龄, 例如: “张三” - 23, “李四” - 24, “王五” - 23, “赵六” - 26获取所有年龄为23的学生信息, 并打印结果.
参考代码
//案例: 模式匹配之匹配for表达式.
object ClassDemo09 {
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(- * 15)
//2.2 格式二: 通过固定值实现.
for((k, 23) - map1) println(k 23)
}
}