基于Java再出发Scala(下)


八、模式匹配*

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(_))
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值