1 类型匹配
1.1 最普通的类型匹配
package com.qf.bigdata
object TestDemo02 {
def main(args: Array[String]): Unit = {
var sign = 0
val ch = '+'
sign = ch match {
case '+' => 0
case '-' =>1
case _ =>100
}
println(sign)
}
}
/*
var sign = 0
val ch = '+'
ch match {
case '+' => sign = 0
case '-' => sign = -1
case _ => sign = -100
*/
1.2字符串的类型匹配
package com.qf.bigdata
object TestDemo03 {
def main(args: Array[String]): Unit = {
caseDemo3
}
def caseDemo3:Unit = {
"hello world ~".foreach(x =>print(
x match {
case ' ' => "space"
case ch => ch
}
))
}
}
1.3 类的类型匹配
我先说明一下这个结构哈:
就是先定义一个父类,再定义两个子类继承这个父类,
定义一个函数,传入一个类,通过类型匹配可以获取子类对象并且调用子类的方法。
package com.qf.bigdata
object TestDemo04 {
//这里的话就采取了继承的关系
class Person(name:String,age:Int){}
class Teacher(name:String,age:Int)extends Person(name:String,age:Int){
def work() = print(s"${age}的${name}正在教书")
}
class Student(name:String,age:Int)extends Person(name:String,age:Int){
def work() = print(s"${age}的${name}正在学习")
}
//下面这个方法是传了一个相当于javabean
def doSth(person:Person) ={
person match {
case teacher: Teacher => teacher.work()
case student: Student => student.work()
case _ => print("类型不匹配")
}
}
def main(args: Array[String]): Unit = {
doSth(new Student("cidy",18))
}
}
1.4 数组类型的匹配
package com.qf.bigdata
//匹配数组
object TestDemo05 {
def main(args: Array[String]): Unit = {
val array = Array(-1,2)
array match {
case Array(x ,y) =>print(s"x=${x},y=${y}") //匹配两个元素的数组
case Array(0, _*) =>print(s"Array(0,_*)") //匹配第一个数组元素的0,后面元素任意
case _ => print("default")
}
}
}
1.5 元组的匹配类型
元组的类型匹配只能按照个数,不能搞可变参数,至于类型匹配的case _就不用加了,因为加了也没啥用。
元组的个数就是按照它自身的个数来就好
package com.qf.bigdata
object TestDemo06 {
def main(args: Array[String]): Unit = {
val tup = (1,2,3)
tup match {
case (first,second,third) => {
println(s"first num is ${first}")
println(s"second num is ${second}")
println(s"third nums is ${third}")
}
}
}
}
1.6 把模式匹配放到单词统计程序中去
package com.qf.bigdata
object TestDemo07 {
def main(args: Array[String]): Unit = {
val array:Array[String] = Array("hello world","hello hadoop","hello jdk")
//原始方法 就是先压平,分组,map映射统计(不要丢map的括号)
val w2c :Map[String,Int] = array.flatMap(_.split("\\s+")).groupBy(word =>word)
.map(kv =>(kv._1,kv._2.length)) //我发现我自己老丢一个map()
//使用匹配类型
// val w2cMathch:Map[String,Int] = array.flatMap(_.split("\\s+")).groupBy(word =>word)
// .map{
// kv => kv match {
// case (key ,value) =>(key,value.length)
// }
// }
//下面这个类型匹配是上面那个的简写
val w2cMatch:Map[String,Int] = array.flatMap(_.split("\\s+")).groupBy(word => word)
.map{case (key,value) => (key,value.length)}
print(w2cMatch.mkString(",")) //mkString就是一个指定拼接符的,组合成一个字符串然后输出
}
}
1.7 样例类的基本使用
所谓样例类,就是case class,是scala中的一种专门用来携带数据的class,类似于java中的javabean。一般我们定义样例类都需要定义样例类的主构造器,其所有的字段都在主构造器中完成申明,样例类会自动的给他们提供getter/setter方法。
样例类的主构造器接受的参数通常不需要使用var或val修饰,scala会自动的使用val修饰和普通类一样,当然如果需要,也可以自定义var或val。
scala会自动为样例类生成伴生对象,也就是object,并且定义apply方法,这个方法和主构造的参数列表一样。
package com.qf.bigdata
object TestDemo08 {
def caseDemo() {
abstract class Expr
case class Var(name:String) extends Expr //继承父类
case class UnOp(expr:Expr,oprator:String) extends Expr //符号
case class Number(num:Double) extends Expr //数字类
case class BinOp(left:Expr,operator:String,right:Expr) extends Expr //这个可以用来搞四则运算
def test(expr: Expr) = {
expr match {
case Var(name) => print(s"Var is ${name}")
case Number(num) => print(s"Number is ${num} ")
case UnOp(Var(name),"+") => print(name+"+")
case BinOp(Number(num1), "+", Number(num2)) => print(s"${num1 + num2}")
case BinOp(Number(num1), "-", Number(num2)) => print(s"${num1 - num2}")
case BinOp(Number(num1), "*", Number(num2)) => print(s"${num1 * num2}")
}
}
test(BinOp(Number(1),"+",Number(2)))
}
def main(args: Array[String]): Unit = {
caseDemo()
}
}
1.8 模拟枚举
1.8.1 枚举的一般定义方式
package com.qf.bigdata
//枚举的普通定义方法
object TestDemo09 {
//先定义一个枚举对象
object TrafficLight extends Enumeration {
val GREEN,YELLOW,RED = Value
}
def main(args: Array[String]): Unit = {
def accrossRoad(light:TrafficLight.Value) = {
light match {
case TrafficLight.GREEN =>print("绿灯行")
case TrafficLight.RED =>print("红灯停")
case TrafficLight.YELLOW => print("等绿灯")
case _ => print("信号灯故障,看交警手势!")
}
}
accrossRoad(TrafficLight.YELLOW)
}
}
1.8.2 密封类 (不常用哈)
一个密封类定义在了一个文件中,那么只有在这个文件中才能使用密封类。我们一般会在本文件中定义这个密封类的子类提供给外界调用。
package com.qf.bigdata
//封装类
object TestDemo10 {
sealed abstract class TrafficLight2(color:String)
case class RED(red:String) extends TrafficLight2(red)
case class GREEN(green:String) extends TrafficLight2(green)
case class YELLOW(yellow:String) extends TrafficLight2(yellow)
def accrossRoad(light:TrafficLight2) = {
light match {
case RED(red) => print(red)
case GREEN(green) => print(green)
case YELLOW(yellow) => print(yellow)
}
}
def main(args: Array[String]): Unit = {
accrossRoad(RED("您已经触犯交通安全法"))
}
}
2、隐式转换
2.1普通函数的隐式转换
package com.qf.bigdata
object Utils {
implicit def double2Int(d:Double):Int = d.toInt
}
package com.qf.bigdata
import com.qf.bigdata.Utils._
//上面那个包要注意,就_不能少!
object TestDemo11 {
def main(args: Array[String]): Unit = {
val x:Int = 3.5 //调用了隐式函数
}
}
2.2 就是使用scala的read读取文件,一般的File是无法读取文件的
我们读取a.txt
package com.qf.bigdata
import java.io.File
import scala.io.Source
object Utils {
implicit def double2Int(d:Double):Int = d.toInt
//把一个普通的file对象转换为RichFile对象
implicit def file2RichFile(file:File):RichFile = new RichFile(file)
}
//就是通过scala中的read读取文件
class RichFile(file:File){
def read() = Source.fromFile(file).getLines()
}
package com.qf.bigdata
import java.io.File
import com.qf.bigdata.Utils._
object TestDemo11 {
def main(args: Array[String]): Unit = {
val x:Int = 3.5
//使用一个file类
val file = new File("D:\\data\\a.txt")
print(file.read().mkString(","))
}
}