大数据基础之Scala——Scala扩展(模式匹配、偏函数、正则表达式、隐式类)

match表达式

  • 类似Java switch语句
     - 能处理类型所有类型
     - 不需要break
     - 能够生成值
val firstArg=if(args.length>0) args(0) else ""
firstArg match{
    case "salt" => println("pepper")
    case "chips" => println("salsa")
    case "eggs" => println("bacon")
    case _ => println("huh?")	            //以上未列出的值,使用“_”表示
}

样例类的模式匹配

  • 模式匹配
     - 检查某个值(value)是否匹配某一个模式的机制,一个成功的匹配同时会将匹配值解构为其组成部分
//基本模式匹配
def matchTest(x:Int):String = x match{
	case 1 => "one"
	case 2 => "two"
	case _ => "many"
}
matchTest(3)           //many
matchTest(1)           //one
//模式守卫(在模式后面加上if条件)
def matchTest2(x:Int):String = x match{
	case i if i==1 => "one"
	case i if i==2 => "two"
	case _ => "many"
}
matchTest2(3)       //many
matchTest2(1)       //one
//仅匹配类型
def matchTest3(x:Any):String = x match{
	case x:Int => "Int"
	case x:String => "String"
	case _ => "Any"
}
matchTest3(3.0)        //Any
matchTest3(1)          //Int
//样例类的模式匹配
def matchTest4(x:Student) = x match{
	case Student(name,19) => println(name)
	case Student("Tom",age) => println(age)
	case Student(name,age) => println(name,age)
	case _ => println("no matches")
}
matchTest4(Student("jason",19))               //jason
matchTest4(Student("Tom",32))                 //32
matchTest4(Student("Amy",25))                //Amy,25

非样例类的模式匹配

  • 单例对象中指定unapply( )方法时,称为提取器对象
  • unapply( )方法接受一个实例对象,返回最初创建它所用的参数
class Student(_name:String,_age:Int){
	var name = _name
	var age = _age
}
object Student{
	def apply(name:String,age:Int):Student = new Student(name,age)
	def unapply(arg:Student):Option[(String,Int)] = {
		if(arg==null){
			None
		}else{
			Some(arg,name,arg.age)
		}
	}
}

def matchTest(x:Student) = x match{
	case Student(name,age) if age<=20 => println("young")
	case Student(name,age) if age>20 => println("old")
}
matchTest(Student("jason",19))               //young

偏函数

  • 偏函数是只对函数定义域的一个子集进行定义的函数
  • partialFunction[-A,+B]是一个特质
     - A为函数定义域,B为偏函数返回值类型
     - apply()
     - isDefinedAt()
//自定义偏函数
val inc = new PartialFunction[Any,Int]{
	def apply(any:Any) = any.asInstanceOf[Int]+1
	def isDefinedAt(any:Any) = if(any.isInstanceOf[Int] true else false)
}

List(1,2,3,"four").collect(inc)

//返回一个偏函数
val pf:PartialFunction[Any, Int]={case x:Int=>x+1} 

//输出List(2,3,4)
List(1,2,3,"four").collect(pf)  

正则表达式

  • Scala支持多种正则表达式解析方式
     - String.matches()方法
     - 正则表达式模式匹配
     - scala.util.matching.Regex API
//String.matches
"!123".matches("[a-zA-Z0-9]{4}")  //false
"34Az".matches("[a-zA-Z0-9]{4}")  //true

//模式匹配,Regex实现了提取器
val regstr = "([a-z]{3})".r     //使用.r方法可使任意字符串变成一个regex实例
    "abc" match {
      case regstr(x)=>println(x)
      case _ =>println("xixi")
    }
  • scala.util.matching.Regex(方法详解)
     - findFirstMatchIn() 返回第一个匹配 (Option[Match])
     - findAllMatchIn() 返回所有匹配结果(正则迭代器)
     - findAllIn() 返回所有匹配结果(字符串数组迭代器)
val str = "{browser:chrome,screen:1024x768,pageName:http://www.baidu.com}"
val reg = "([a-zA-Z]+):([a-zA-Z0-9:/\\.]+)".r

reg.findAllMatchIn(str).foreach(x=>println(s"key:${x.group(1)},value:${x.group(2)}"))
    reg.findAllIn(str).foreach(x=>x match {case reg(k,v)=>println(k,v)})
  • 捕获分组结果:
val studentPattern:Regex="([0-9a-zA-Z-#() ]+):([0-9a-zA-Z-#() ]+)".r
val input="name:Jason,age:19,weight:100"

for(patternMatch<-studentPattern.findAllMatchIn(input)){
    println(s"key: ${patternMatch.group(1)} value: ${patternMatch.group(2)}")
}
  • 字符串替换:
//search
val nums = "[0-9]+".r.findAllIn("123 Main Street Suite 2012")
nums.next                // -> 123
nums.next                // -> 2012

//replace
"[0-9]+".r.replaceFirstIn("234 Main Street Suite 2034", "567") //234->567   
"[0-9]+".r.replaceAllIn("234 Main Street Suite 2034", "567") //234、2034->567
  • 在字符串中模式匹配
val date = """(\d\d\d\d)-(\d\d)-(\d\d)""".r
"2014-05-23" match {
    case date(year, month, day) => println(year,month,day)
}
"2014-05-23" match {
    case date(year, _*) => println("The year of the date is " + year) 
} 
"2014-05-23" match {
    case date(_*) => println("It is a date")
}

隐式类

  • 隐式类:用implicit关键字修饰的类,其主构造器可用于隐式转换
      - 只能在类、Trait、对象(单例对象、包对象)内部定义
      - 构造器只能携带一个非隐式参数
      - 隐式类不能是case class
      - 在同一作用域内,不能有任何方法、成员或对象与隐式类同名

  • 隐式转换
      - 隐式参数、隐式函数
        - 隐式转换函数是以implicit关键字声明的带有单个参数的函数
        - 这种函数将会自动应用,将值从一种类型转换到另一种类型
    案例研究:

//隐式参数
object ImplicitTest {
  /**
    * Implicit实现隐式参数
    */
    object Context{
    implicit val str:String = "implicit parameter"
   }
  object Parameter{
    def print(context:String)(implicit prefix:String): Unit ={
      println(prefix+":"+context)
    }
  }
  def main(args: Array[String]) {
    Parameter.print("Hello")("Scala")
    //在此使用隐式参数
    import Context._
    Parameter.print("Scala")
  }
}

运行结果:
Scala:Hello
implicit parameter:Scala
//隐式转换
object ImplicitTest {
  /**
    * Implicit实现隐式参数
    */
    object Context{
    implicit val str:String = "implicit parameter"
   }
  object Parameter{
    def print(context:String)(implicit prefix:String): Unit ={
      println(prefix+":"+context)
    }

  }

  def main(args: Array[String]) {
    Parameter.print("Hello")("Scala")
    //在此使用隐式参数
    import Context._
    Parameter.print("Scala")
  }

}

运行结果:
Scala:Hello
implicit parameter:Scala
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值