1.25
匹配样例类
要匹配的对象必须声明为 Any。
格式:
对象名 match{
case 样例类型1(字段1, 字段2..) => 表达式1
case 样例类型2(字段1, 字段2..) => 表达式2
case 样例类型3(字段1, 字段2..) => 表达式3
case _ => 表达式4 //默认项
}
示例:
object ClassDemo {
case class Customer(name:String, age:Int)
case class Order(id:Int)
def main(args: Array[String]): Unit = {
val a:Any = Customer("sjh", 20)
a match {
case Customer => println("是customer")
case Order => println("是order")
case _ => println("未匹配")
}
}
}
匹配集合
匹配数组
def main(args: Array[String]): Unit = {
//定义三个数组
val arr1 = Array(1, 2, 3)
val arr2 = Array(0)
val arr3 = Array(0 , 1, 2, 3,4)
arr1 match {
case Array(1, _, _) => println("长度为3,首元素为1")
case Array(0) => println("长度为1,元素0")
case Array(0, _*) => println("首元素0,其余任意")
}
}
匹配列表
def main(args: Array[String]): Unit = {
//定义三个列表
val list1 = List(1, 2, 3)
val list2 = List(0)
val list3 = List(0, 1, 2, 3,4)
list3 match {
case List(1, _, _) => println("长度为3,首元素为1")
case List(0) => println("长度为1,元素0")
case List(0, _*) => println("首元素0,其余任意")
}
//等价于
list2 match {
case 1 :: _ :: _ ::Nil => println("长度为3,首元素为1")
case 0 :: Nil => println("长度为1,元素0")
case 0 :: _ => println("首元素0,其余任意")
}
}
匹配元组
def main(args: Array[String]): Unit = {
//定义三个元组
val a = (1, 2, 3)
val b = (3, 4, 5)
val c = (3, 4)
a match {
case (1, _, _) => println("长度为3,首元素为1")
case (_, _, 5) => println("长度为3,尾元素为5")
case _ => println("不匹配")
}
}
变量声明中的模式匹配
在定义变量时,可以使用模式匹配快速获取数据
生成包含 0-10的数字,使用模式匹配分别获取第2、3、4个元素
生成包含 0-10的列表,使用模式匹配分别获取第1、2个元素
def main(args: Array[String]): Unit = {
val arr = (0 to 10).toArray
val Array(_, x, y, z, _*) = arr
println(x, y, z)//(1,2,3)
val list = (0 to 10).toList
val List(a, b, _*) = list
val c :: d ::tail = list
println(a, b)//(0,1)
println(c, d)//(0,1)
}
匹配 for 表达式
定义变量记录学生姓名和年龄,获取所有年龄为20的学生信息:
def main(args: Array[String]): Unit = {
val map = Map("sjh" -> 20, "a" -> 21, "asx" -> 20)
//方式一 if
for((k, v) <- map if v == 20)
println(k, v)
//方式二 固定值
for((k, 20) <- map)
println(k, 20)
}
Option 类型
用来避免空指针异常,具体值使用 Some(x),空值使用 None
示例:定义一个两数相除的方法,使用 Option 类型封装结果
object ClassDemo {
def divide(a:Int, b:Int): Option[Int] = {
if(b == 0)
None
else
Some(a / b)
}
def main(args: Array[String]): Unit = {
divide(10, 0) match {
case None => println("除数不能为 0")
case Some(x) => println(s"结果为$x")
}
}
}
偏函数
可以配合集合的函数式编程简化代码。
偏函数是指 被包在花括号内没有 match 的一组 case语句。
示例:
def main(args: Array[String]): Unit = {
val pf:PartialFunction[Int, String] = {
case 1 => "一"
case 2 => "二"
case _ => "未匹配"
}
println(pf(1))//一
}
偏函数可结合 map 函数使用。
定义一个列表包含1-10的数字,将1-3的数字转为[1-3],4-8的数字转为[4-8],其余数字转为(8-*]
def main(args: Array[String]): Unit = {
val list = (1 to 10).toList
val list1 = list.map {
case x if x >= 1 && x <= 3 => "[1-3]"
case x if x >= 4 && x <= 8 => "[4-8]"
case _ => "(8,*]"
}
println(list1)//List([1-3], [1-3], [1-3], [4-8], [4-8], [4-8], [4-8], [4-8], (8,*], (8,*])
}
正则表达式
Scala 提供了 Regex 类定义正则表达式
要构造一个 Regex 对象直接使用 String 类的 r 方法即可
建议使用三个双引号表示正则表达式,不需要对其中的反斜杠转义。
格式:
val 正则对象名 = """具体正则表达式""".r
示例:校验邮箱
def main(args: Array[String]): Unit = {
val regex = """.+@.+\.com""".r
val email = "sad@qq.com"
if(regex.findAllMatchIn(email).nonEmpty)
println("合法")
else
println("不合法")
}
示例:过滤出不合法的邮箱
def main(args: Array[String]): Unit = {
val regex = """.+@.+\.com""".r
val emailList = List("sad@.com", "asda@qq.com", "fuck@,cn")
val list = emailList.filter((x) => regex.findAllMatchIn(x).isEmpty)
println(list)//List(sad@.com, fuck@,cn)
}
示例:获取邮箱运营商
def main(args: Array[String]): Unit = {
//括号可以充当分组角色,用来提取其中内容
val regex = """.+@(.+)\.com""".r
val emailList = List("sad@.com", "asda@qq.com", "fuck@,cn")
val list = emailList.map{
case x @ regex(company) => x -> company
case x => x -> "未匹配"
}
println(list)//List((sad@.com,未匹配), (asda@qq.com,qq), (fuck@,cn,未匹配))
}
异常处理
捕获异常
该方式处理完异常,程序会继续执行
抛出异常
该方式处理完异常,程序会终止执行
def main(args: Array[String]): Unit = {
//捕获异常
try{
val i = 10 / 0
}catch {
case _:ArithmeticException => println("算术异常")
case _ => println("其他异常")
}finally {
println("一般用来释放资源")
}
//抛出异常
throw new Exception("发生异常")
}
提取器
一个类如果要支持模式匹配,必须要实现一个提取器。
提取器就是指 unapply 方法。
样例类自动实现了 unapply 方法。
要实现提取器,只需要在该类的伴生对象中实现一个unapply 方法即可。
示例:
object ClassDemo {
class Student(var name:String, var age:Int)
object Student{
//apply 根据给定字段将其封装为 Student 类型对象
def apply(name: String, age: Int): Student = new Student(name, age)
//unapply 根据传入的学生对象,获取其各个属性值
def unapply(s: Student): Option[(String, Int)] = {
if(s == null)
None
else
Some(s.name, s.age)
}
}
def main(args: Array[String]): Unit = {
val s = Student("sjh", 24)
//获取 s 的属性
//通过 unapply
println(Student.unapply(s))
//通过模式匹配 需要实现 unapply方法
s match {
case Student(name, age) => println(s"$name,$age")
case _ => println("未匹配")
}
}
}
案例:随机职业
提示用户录入一个数字(1-5),然后根据数字打印出他的工作。
def main(args: Array[String]): Unit = {
println("请输入一个数字,1-5:")
val num = StdIn.readInt()
num match {
case 1 => println("BAT offer")
case 2 => println("BAT offer")
case 3 => println("BAT offer")
case 4 => println("BAT offer")
case 5 => println("BAT offer")
case _ => println("在家科研,哪都别去")
}
}

浙公网安备 33010602011771号