模式匹配是Scala中非常有特色,非常强大的一种功能。模式匹配,其实类似于Java中的swich case语法,即对一个值进行条件判断,然后针对不同的条件,进行不同的处理。但是Scala的模式匹配的功能比Java的swich case语法的功能要强大地多,Java的swich case语 法只能对值进行匹是Scala的模式匹配除了可以对值进行匹配之外,还可以对类型进行匹配、对Array和List的元素情况进行匹配、对case class进行匹配、甚至对有值或没值(Option) 进行匹配
1、典型的模式匹配场景
1.1 匹配字符串
object Test_zfc {
def main(args: Array[String]): Unit = {
val arr=Array("a","b","c")
//随机获取数组的任意元素
val index=Random.nextInt(3)
val value=arr(index)
//模式匹配
value match{
case "a" => println("匹配到字符串a")
case "b" => println("匹配到字符串b")
case "c" => println("匹配到字符串c")
case _ => println("null") //表示所有的都没有匹配到执行这里
}
}
}
1.2 匹配类型
import scala.util.Random
object test_mspp {
def main(args: Array[String]): Unit = {
//定义数组
val arr=Array("aa",1,2,3.3,true)
//随机获取数组的任意元素
val index=Random.nextInt(arr.length)
//获取值
val value =arr(index)
//模式匹配获取数值类型
value match {
case a:Int if(a==1 | a==2) =>{println("Int")}
case b:String if(b=="aa") =>{println("String")}
case c:Boolean if(c==true) =>{println("Boolean")}
case d:Double if(d==3.3) =>{println("Double")}
case _ =>println("null")
}
//或者
val arr=Array("a",8,4.1,true)
//随机获取数组的任意元素
val index=Random.nextInt(arr.length)
val value=arr(index)
//模式匹配
value match{
case x:Int => println("Int")
case y:String => println("String")
case z:Double => println("Double")
case flag:Boolean => println("Boolean")
case _ => println("null") //表示所有的都没有匹配到执行这里
}
}
}
1.3 匹配数组、元组、集合
//匹配数组
import scala.util.Random
object test_mspp {
def main(args: Array[String]): Unit = {
val arr2 =Array(1,2,3)
arr2 match {
case Array(1,x,y) =>{println(1,x,y)}
case Array(_)=>{println("只匹配一个元素得数组")}
case Array(1,_*)=>{println("1开头的多个元素的数组")}
}
}
}
//匹配元组
object test_mspp {
def main(args: Array[String]): Unit = {
val tu=(1,"lala",2.2)
tu match {
case (0,a,b)=>{println("匹配到0开头的三个元素的元组")}
case (_,a,b)=>{println("匹配到任意开始的三个元素的元组")}
case _=>{println("什么也不匹配")}
}
}
}
//匹配集合(list)
import scala.util.Random
object test_mspp {
def main(args: Array[String]): Unit = {
val li1=List(1,2,3,5,4)
li1 match {
case 1::Nil=>println("只匹配到元素为1的一个ilst")
case a::y::Nil=>println("只匹配到两个元素的list")
case 1::tail=>println("匹配到开头为1的所有list")
case _=>println("null")
}
}
}
1.4 匹配异常
object exectionDome extends App {
try {
val i =4 / 0
}catch {
case e:ArithmeticException=>throw new RuntimeException("除数不能为0")
case e:Exception=>println(e.getMessage())
}finally {
println("结束")
}
}
2、偏函数
val li2 =List(1,2,3,4,"lala")
def par:PartialFunction[Any,Int]={
case i:Int =>{i+1}
}
println(li2 collect par)
}
}
输出结果:
List(2, 3, 4, 5)
3、样例类
转载原文链接:https://blog.csdn.net/accptanggang/article/details/78575710
/*
* 样例类Case Class
* Case Class一般被翻译成样例类,它是一种特殊的类,能够被优化以用于模式匹配。
* 当一个类被声名为case class的时候,scala会帮助我们做下面几件事情:
* 1、构造器中的参数如果不被声明为var的话,它默认的是val类型的,但一般不推荐将构造器中的参数声明为var。
* 2、自动创建伴生对象,同时在里面给我们实现子apply方法,使我们在使用的时候可以不直接使用new创建对象。
* 3、伴生对象中同样会帮我们实现unapply方法,从而可以将case class应用于模式匹配。
* 4、实现自己的toString、hashCode、copy、equals方法
* 除此之此,case class与其它普通的scala类没有区别
*/
//抽象Person类
abstract class Person
//样例类Student
case class Student(name: String, age: Int, stuNo: String) extends Person
//样例类Teacher
case class Teacher(name: String, age: Int, teaNo: String) extends Person
//样例类 Nobody
case class Nobody(name: String) extends Person
object CaseClassDemo {
def main(args: Array[String]): Unit = {
//case class会自动生成apply方法,创建对象时无需用new
val p: Person = Student("lisi", 20, "101")
//match case模式匹配
p match {
case Student(name, age, stuNo) => println(s"学生:$name, $age, $stuNo")
case Teacher(name, age, teaNo) => println(s"老师:$name, $age, $teaNo")
case Nobody(name) => println(s"其他人:$name")
}
/*case class常用方法,定义case class便会自动生成对应的toString,hashCode,equals,copy等方法,*/
val teacher = Teacher("jack", 30, "0010")
//toString方法
println(teacher.toString)
//无参copy方法
val teacher2 = teacher copy()
/*特别注意:
equals方法是检查值是否相等,而eq方法检查的是引用是否相等,
所以如果比较的对象是null那么==调用的是eq,不是null的情况调用的是equals。
在Java中如果要对两个对象进行值比较,那么必须要实现equals 和hashCode方法。
而在scala中为开发者提供了case class,默认实现了equals 和hashCode方法。*/
//eq方法进行比较
println(teacher.eq(teacher2))
//equals方法根据对象内容进行比较
println(teacher equals (teacher2))
//==方法进行比较
println(teacher == teacher2)
hashcode方法
println(teacher hashCode())
println("====================================")
println(teacher2.toString)
//带一个参数的copy方法
println(teacher2.copy("tony").toString)
//带二个参数的copy方法
println(teacher2.copy("tony", 25).toString)
//带三个参数的copy方法
println(teacher2.copy("tony", 25, "1002").toString)
println("====================================")
/*case class在实用应用中的用途:
某个类一旦被定义为case class,则编译器会自动生成该类的伴生对象,伴生对象中包括了apply方法及unapply方法,
apply方法使得我们可以不需要new关键字就可以创建对象,
而unapply方法,则使得可以方便地应用在模式匹配当中,
另外编译器还自动地帮我们实现对应的toString、equals、copy等方法。
在实际中,case class除了在模式匹配时能发挥其强大的威力之外,在进行其它应用时,也显示出了其强大的功能。*/
}
}