文章目录
八、模式匹配*
1.基本语法
* 变量名/表达式 match {
* case 匹配条件 => {
* 匹配上之后执行的逻辑
* }
* case 匹配条件 => {
* 匹配上之后执行的逻辑
* }
* .....
* case _ => {
* 其他情况
* }
* }
注意:模式匹配是有返回值的,返回值就是{}中可执行代码的最后一个表达式
object MatchDefined {
def main(args: Array[String]): Unit = {
val word = StdIn.readLine("请输入一个单词:")
word match {
case "hadoop" =>{println("输入的是:hadoop")}
case "spark" =>{println("输入的是:spark")}
case _=>{println("其他情况。。。。")}
}
}
}
执行结果:
请输入一个单词:spark
输入的是:spark
2.模式守卫
基本语法:
* 守卫:
* 变量名/表达式 match {
* case 匹配条件 if 布尔表达式=> {
* 匹配上之后执行的逻辑
* }
* case 匹配条件 => {
* 匹配上之后执行的逻辑
* }
* .....
* case _ => {
* 其他情况
* }
* }
object MatchIf {
def main(args: Array[String]): Unit = {
val word = StdIn.readLine("请输入一个单词:")
word match {
case x if x.contains("s")=>{println(s"${x}包含s")}
case x if x.length==10=>{println(s"${x}长度为10")}
case _=>{
println("其他情况")
}
}
}
}
执行结果:
请输入一个单词:helloworld
helloworld长度为10
3.模式匹配类型
3.1匹配常量
可以匹配所有的字面量,包括字符串,数字,布尔值等等
3.2匹配类型
object MatchType {
def main(args: Array[String]): Unit = {
val list = List[Any](1,2.0,"scala",true)
val index = Random.nextInt(list.length)
val value = list(index)
value match {
case x:Int=>{
println(s"${x}是Int类型")
}
case x:Boolean=>{
println(s"${x}是布尔值")
}
case x:Double=>{
println(s"${x}是Double")
}
case _=>{
println("其他类型")
}
}
}
}
执行结果:
true是布尔值
3.3匹配数组
object MatchArray {
def main(args: Array[String]): Unit = {
val arr = Array[Any](1,"yilei","china")
arr match{
case Array(x:Int,y:String,z:String)=>{
println(s"数组元素分别为:${x},${y},${z}")}
case Array(x:Int,y:String,z:Boolean)=>{
println(s"数组元素分别为:${x},${y},${z}")
}
case Array(x,_*)=>{
println("数组最少有一个元素")
}
case _=>println("其他情况")
}
}
}
输出结果:
数组元素分别为:1,yilei,china
3.4匹配列表
object MatchList {
def main(args: Array[String]): Unit = {
val list = List[Any](10,11,10,9)
list match{
case List(x)=>println("list只有一个元素")
case List(x:Int,y:Int,z:Int)=>println("list里三个Int元素")
case List(_,_,_)=>println("list三个元素")
case _=>println("其他情况")
}
val list1 = List[String]("spark","hadoop")
list1 match{
case x::Nil =>println("List只有一个元素")
case (x:String)::(y:String)::Nil=>println("集合三个元素")
case _=>println("其他情况")
}
/*
泛型擦除:
List的泛型只用于写代码期间提示程序员List中应该传入什么类型的数据
在运行期间,会将List的泛型干掉
*/
list match{
case x:List[String]=>println("List[String]")
case x:List[Int]=>println("List[Int]")
case _=>println("其他情况")
}
}
}
运行结果:
其他情况
集合三个元素
List[String]
3.5匹配元组
object MatchTuple {
def main(args: Array[String]): Unit = {
val t1:(Any,Any,Any)=("yilei",20,"china")
t1 match {
case (x:Int,y:Int,z:String)=>println("int,int,String")
case (x,y,z)=>println("三元元组")
case _=>println("其他情况")
}
val list = List[(String,(String,(String,Int)))](
("湖南",("长沙",("雨花区",56))),
("江西",("南昌",("红谷滩区",46))),
("广东",("广州",("天河区",108)))
)
//获取省会最大人口区
list.map(x=>{x._2._2._2}).foreach(println(_))
println("="*50)
//实际应用场景
list.map(x=>x match{
case (province,(city,(area,population)))=>population
}).foreach(println(_))
}
}
输出结果:
三元元组
56
46
108
==================================================
56
46
4.样例类与样例对象
object MatchObject {
case class Province(provinceName:String,city:City)
case class City(cityName:String,area:Area)
case class Area(areaName:String,population:Int)
def main(args: Array[String]): Unit = {
val list1 = List[Province](
Province("湖南",City("长沙",Area("雨花区",56))),
Province("江西",City("南昌",Area("红谷滩区",46))),
Province("广东",City("广州",Area("天河区",108)))
)
list1.map(x=>{
x.city.area.population
}).foreach(println(_))
}
}
结果输出:
56
46
108
样例类:
语法:case class 类名([val/var] 属性名:类型,…)
【val/var可以省略,省略的情况默认是:val】
创建对象:类型(值1,值2…)
样例类其实就是伴生对象与伴生类封装
object MatchObject {
//样例类
case class Person(name:String,age:Int)
def main(args: Array[String]): Unit = {
val person1 = Person("yilei",20)
val person2 = Person("xiaolei",10)
println(person1.name)
println(person1.age)
println(person1.eq(person2))
}
}
输出结果:
yilei
20
false
样例对象:
语法:case object 名称[用于枚举值]
object MatchObject {
//样例对象
case object Sex
def main(args: Array[String]): Unit = {
val sex = Sex
val sex1 = Sex
println(sex.eq(sex1))
}
}
输出结果:
true
匹配样例类:
object MatchObject {
//样例类
case class Person(name:String,age:Int)
def main(args: Array[String]): Unit = {
val person1 = Person("yilei",20)
//匹配样例类
person1 match {
case Person(name,age)=>println(s"${name} ${age}")
}
}
}
输出结果:
yilei 20
5.声明变量时匹配元组
object MatchParam {
def main(args: Array[String]): Unit = {
//通常做法
val person = ("yilei",13,"china")
person match {
case (name,age,address)=>println(s"name:${name} age:${age} address:${address}")
}
println("="*50)
//声明变量时匹配元组
val (name,age,address)=("yilei",20,"china")
println("name:"+name)
println("age:"+age)
println("address:"+address)
}
}
结果输出:
name:yilei age:13 address:china
==================================================
name:yilei
age:20
address:china
6.for表达式中的模式匹配
object MatchParam {
def main(args: Array[String]): Unit = {
val map = Map[String,Int]("yilei"->20,"xiolei"->13)
//通常做法
for(element<-map){
println(element)
}
println("="*50)
//for循环模式匹配
for((name,age)<-map){
println("name:"+name+" age:"+age)
}
}
}
结果输出
(yilei,20)
(xiolei,13)
==================================================
name:yilei age:20
name:xiolei age:13
7.偏函数中的模式匹配
* 偏函数: 没有match关键字的模式匹配
* 语法:
* val func: PartialFunction[IN,OUT] = {
* case 条件 => ..
* case 条件 => ..
* case _ => ..
* }
* IN: 函数的参数类型
* OUT: 函数的返回值类型
object PartialFunction {
def main(args: Array[String]): Unit = {
val list = List[(String,(String,(String,Int)))](
("湖南",("长沙",("雨花区",56))),
("江西",("南昌",("红谷滩区",46))),
("广东",("广州",("天河区",108)))
)
//通常情况
list.map(x=>x match {
case (province,(city,(area,population)))=>population
}).foreach(println(_))
println("="*50)
//使用偏函数
val func:PartialFunction[(String, (String, (String, Int))),Int]={
case (province, (city, (area, population))) => population
}
//list.map(func).foreach(println(_))
//简化
list.map {
case (province, (city, (area, population))) => population
}.foreach(println(_))
}
}
执行结果:
56
46
108
==================================================
56
46
108
object PartialFunction {
def main(args: Array[String]): Unit = {
val list = List[Any](1,2,"String",true)
//需求:集合中元素为Int类型的+1,并去掉其他类型
list.filter(_.isInstanceOf[Int]).map(_.asInstanceOf[Int]+1).foreach(println(_))
println("="*20)
//collect底层调用偏函数,会先通过isDefineAt方法判断元素是否否和case中的要求,不符合的会过滤掉
list.collect{case x:Int=>x+1}.foreach(println(_))
}
}
执行结果:
2
3
====================
2
3
九、异常*
* java中对于异常的处理方式:
* 1、捕获异常: try{}catch{}finally{}
* 2、抛出异常: throw new Exception(..) [java中抛出异常,在方法上需要通过throws关键字将异常抛出]
* scala中直接将throws关键字删掉了
* scala中对于异常的处理方式:
* 1、捕获异常
* 1、try{}catch{}finally{} [只用于一种场景: 在代码中需要获取外部链接的时候使用]
* 2、Try(代码).getOrElse(默认值)
* Try有两个子类:
* Success: 代表Try中的代码执行成功,代码执行结果封装在Success中,可以通过get方法获取代码执行结果
* Failure: 代表Try中的代码执行失败,后续可以通过filter将非法数据过滤
* isSuccess: 是否成功
* isFailure: 是否失败
* 2、抛出异常: throw new Exception(..)
object Exception {
def main(args: Array[String]): Unit = {
val list = List("1001 yilei 20","1002 30","1003 xiaobai","1004 honger 12")
list.map(x=>{
try {x.split(" ")(2).toInt}catch {case e:Exception=>0}
}).foreach(println(_))
println("="*20)
//对异常数据不做处理
list.map(x=>{
Try (x.split(" ")(2).toInt)
}).filter(_.isSuccess).map(_.get).foreach(println(_))
}
}
执行结果:
20
30
0
12
====================
20
30
12
十、隐式转换
1.隐式方法
import java.io.File
//导入隐式转换方法
import com.yilei.charpter01.A._
import scala.io.{BufferedSource, Source}
class RichFile(file:File){
def toBuffer() = {
Source.fromFile(file,"utf-8")
}
}
object $01_ImplicitMethod{
/**
* 隐式转换[悄悄的转换]:
* 隐式转换方法[悄悄的将一个类型【A】转成另一个类型【B】]:
* 语法: implicit def 方法名(参数名:参数类型【A】):返回值类型【B】 = {方法}
* 隐式转换方法的两种使用场景:
* 1、参数类型与目标类型不一致
* 2、对象使用了不属于自己的属性和方法/函数
* 以上两种情况会自动的从当前作用域[包含父作用域以及父类的作用域]中调用隐式转换方法
* 如果隐式转换方法不在当前作用域,要想使用隐式转换方法必须进行导入: import 包名.类名.方法名
* 注意: 如果有多个隐式转换方法都能满足要求,导入的时候必须明确指定导入哪个隐式转换方法
* 隐式转换参数[悄悄的给方法传值]:
*/
def main(args: Array[String]): Unit = {
val x:Int = 2.0
val file = new File("d:/product.txt")
file.toBuffer()
}
}
2.隐式常量
object $02_ImplictParam {
/**
* 语法:
* 1、定义隐式转换参数:implicit val 变量名:变量类型 = 值
* 2、定义方法,在方法中标识哪个参数后续通过隐式转换参数赋值
* def 方法名(参数名:参数类型,参数名:参数类型,..)(implicit 参数名:参数类型)
*/
def main(args: Array[String]): Unit = {
println(m1(10, 20)(30))
}
implicit val x:Int = 10
def m1(x:Int,y:Int)(implicit z:Int) = x + y + z
}
2.隐式类
import java.io.File
import scala.io.Source
object $03_ImplicitClass {
implicit class RichFile2(val file:File) {
def getLines = Source.fromFile(file).getLines()
}
/**
* 隐式转换类:
* 语法: implicit class 类名【B】[目标类型](val 属性名:类型[待转换类型【A】]){..}
*
* 后续如果A调用B中的方法,只需要将隐式转换类导入就可以了
*
* 隐式类必须定义在class/object中,不能置于最顶层
* 隐式类其实就是隐式转换方法的简化,
* @param args
*/
def main(args: Array[String]): Unit = {
val file = new File("d:/product.txt")
file.getLines.foreach(println(_))
}
}