样例类是一种特殊的类,它可以用来快速定义一个用于保存数据的类(类似于Java POJO类)
语法:
case class 样例类名([var/val] 成员变量名1:类型1, 成员变量名2:类型2, 成员变量名3:类型3) 如果要实现某个成员变量可以被修改,可以添加var默认为val,可以省略需求:
定义一个Person样例类,包含姓名和年龄成员变量创建样例类的对象实例(“张三”、20),并打印它参考代码
package scala.demo object Demo01 { case class Person(name:String,age:Int) def main(args: Array[String]): Unit = { val person = new Person("张三",20) println(person.name+"..."+person.age) } }需求:
定义一个Person样例类,包含姓名和年龄成员变量创建样例类的对象实例(“张三”、20)修改张三的年龄为23岁,并打印参考代码
package scala.demo object Demo02 { case class Person(var name:String,var age:Int) def main(args: Array[String]): Unit = { val person = new Person("张三",20) person.age=23 println(person.name+"..."+person.age) } }apply方法可以让我们快速的通过类名来创建对象
package scala.demo object Demo03 { case class Person(name:String,age:Int) def main(args: Array[String]): Unit = { val person = Person.apply("李四",21) println(person.name+"..."+person.age) } }toString返回样例类名称(成员变量1,成员变量2,成员变量3…),更加方便的查看样例类的成员
package scala.demo object Demo03 { case class Person(name:String,age:Int) def main(args: Array[String]): Unit = { val person = Person("张三",32) println(person.toString) } }样例类自动实现了equals方法,可以直接使用==比较两个样例类是否相同,即所有的成员变量是否相同 示例
创建一个样例类Person,包含姓名、年龄创建名字年龄分别为"李四", 21的两个对象比较它们是否相等 val lisi1 = CasePerson("李四", 21) val lisi2 = CasePerson("李四", 21) println(lisi1 == lisi2) // 输出:true样例类自动实现了hashCode方法,如果成员变量的值相同,则hash的值相同,只要一个不一样,则hash值不一样
示例
创建名字年龄分别为"李四", 21的对象再创建一个名字年龄分别为"李四", 22的对象分别打印这两个对象的哈希值 package scala.demo object Demo03 { case class Person(name:String,age:Int) def main(args: Array[String]): Unit = { val person1 = Person("李四",21) val person2 = Person("李四",23) println(person1.hashCode())//718456491 println(person2.hashCode())//-1043168051 //特殊情况,传入的值不一样,但是hash值一样 val p1 = Person("儿女",10) val p2 = Person("农丰",10) println(p1.hashCode()) println(p2.hashCode()) val p3 = Person("重地",10) val p4 = Person("通话",10) println(p3.hashCode()) println(p4.hashCode()) } }快速创建一个相同的实例对象,可以使用带名参数指定给成员进行复制
示例
创建名字年龄分别为"李四", 21的对象通过copy拷贝,名字为"王五"的对象 package scala.demo object Demo03 { case class Person(name:String,age:Int) def main(args: Array[String]): Unit = { val person1 = Person("李四",21) val wangwu = person1.copy(name = "王五") println(wangwu.name+".."+wangwu.age) } }主要作用在两方向:
定义枚举作为没有任何参数的消息进行传递使用case object 创建样例类对象,样例对象是单例,并且没有主构造器
语法
case object 样例对象名需求说明
定义一个性别Sex枚举,它只有两个实例(男性——Male、女性——Female)创建一个Person类,它有两个成员(姓名、性别)创建两个Person对象(“张三”、男性)、(“李四”、“女”)参考代码
package scala.demo object Demo04 { trait Sex case object Male extends Sex case object Female extends Sex class Person(name:String,sex:Sex) def main(args: Array[String]): Unit = { val zhangsan = new Person("张三",Male) val lisi = new Person("张三",Female) } }scala中有一个非常强大的匹配机制
switch语句类型查询使用模式匹配快速的获取数据在Java中,有switch关键字,可以简化jf条件判断语句,在scala中,可以使用match表达式来代替
语法:
变量 match { case "常量1" => 表达式1 case "常量2" => 表达式2 case "常量3" => 表达式3 case _ => 表达式4 // 默认配 }示例
需求说明
从控制台输入一个单词(使用StdIn.readLine方法)判断该单词是否能够匹配以下单词,如果能匹配,返回一句话打印这句话 单词返回hadoop大数据分布式存储和计算框架zookeeper大数据分布式协调服务框架spark大数据分布式内存计算框架未匹配未匹配参考代码
package scala.demo import scala.io.StdIn object Demo05 { def main(args: Array[String]): Unit = { println("请输入一个词:") val name =StdIn.readLine() val result = name match { case "hadoop"=>"大数据分布式存储和计算框架" case "zookeeper"=>"大数据分布式协调服务框架" case "spark"=>"大数据分布式内存计算框架" case _=>"未匹配" } println(result) } }除了像Java中的switch匹配数据外,match表达式还可以进行类匹配,根据不同的数据类型,来执行不同的逻辑
语法
变量 match { case 类型1变量名: 类型1 => 表达式1 case 类型2变量名: 类型2 => 表达式2 case 类型3变量名: 类型3 => 表达式3 ... case _ => 表达式4 }示例
需求说明
定义一个变量为Any类型,然后分别给其赋值为"hadoop"、1、1.0定义模式匹配,然后分别打印类型的名称参考代码
package scala.demo object Demo06 { def main(args: Array[String]): Unit = { val a:Any = "hadoop" val result = a match { case _:String=>"字符串" case _:Int=>"整数" case _:Double=>"小数" } println(result) } }注意:在scala中,如果case表达式中无需使用到匹配到的变量,可以使用下划线来代替
在scala中,在case中添加if条件判断语句
示例
需求说明
从控制台读入一个数字a(使用StdIn.readInt)如果 a >= 0 而且 a <= 3,打印[0-3]如果 a >= 4 而且 a <= 8,打印[3,8]否则,打印未匹配参考代码
package scala.demo import scala.io.StdIn object Demo07 { def main(args: Array[String]): Unit = { println("请输入一个数字:") val nums = StdIn.readInt() nums match { case _ if nums>=0 && nums <=3 =>println("[0-3]") case _ if nums>=4 && nums <=8 =>println("[4-8]") case _=>println("未匹配") } } }scala可以使用模式匹配样例类,从而可以快速获取样例类中的成员数据
示例
需求说明
创建两个样例类Customer、Order Customer包含姓名、年龄字段Order包含id字段 分别定义两个案例类的对象,并指定为Any类型使用模式匹配这两个对象,并分别打印它们的成员变量值参考代码
package scala.demo object Demo08 { case class Customer(var name:String,var age:Int) case class Order(var id:Int) def main(args: Array[String]): Unit = { val customer:Any=new Customer("张三",20) val order:Any= new Order(1) customer match { case Customer(name,age)=>println(s"姓名:${name},年龄:${age}") case Order(id)=>println(id) case _=>println("未匹配") } } }示例说明
依次修改代码定义以下三个数组 Array(1,x,y) // 以1开头,后续的两个元素不固定 Array(0) // 只匹配一个0元素的元素 Array(0, ...) // 可以任意数量,但是以0开头 使用模式匹配上述数组 参考代码 package scala.demo object Demo09 { def main(args: Array[String]): Unit = { val arr = Array(1,3,5) arr match { case Array(1,x,y)=>println(x+"..."+y) case Array(0)=>println("only 0") case Array(0,_*)=>println("0.......") case _=>println("somethig else ") } } }示例说明
依次修改代码定义以下三个列表 List(0) // 只保存0一个元素的列表 List(0,...) // 以0开头的列表,数量不固定 List(x,y) // 只包含两个元素的列表 使用模式匹配上述列表参考代码
package scala.demo object Demo10 { def main(args: Array[String]): Unit = { val list = List(0,1,2,3,4,5) list match { case 0::Nil=>println("只有0的列表") case 0::tail=>println("0开头的列表") case x::y::Nil=>println(s"列表中只有两个元素${x},${y}的列表") case _=>println("未匹配") } } }示例说明
依次修改代码定义以下两个元组 (1, x, y) // 以1开头的、一共三个元素的元组 (x, y, 5) // 一共有三个元素,最后一个元素为5的元组 使用模式匹配上述元素参考代码
package scala.demo object Demo11 { def main(args: Array[String]): Unit = { val tuple=(1,2,3) tuple match { case (1,x,y)=>println(s"三个元素,1开头的元组:1,${x},${y}") case (x,y,5)=>println(s"三个元素,5结尾的元组:${x},${y},5") case _=>println("未匹配") } } }定义变量的时候,可以使用模式匹配快速的获取数据
需求说明
生成包含0-10数字的数组,使用模式匹配分别获取第二个、第三个、第四个元素参考代码
package scala.demo object Demo12 { def main(args: Array[String]): Unit = { val array = (1 to 10).toArray val Array(_,x,y,z,_*)=array println(x,y,z) } }需求说明
生成包含0-10数字的列表,使用模式匹配分别获取第一个、第二个元素参考代码
package scala.demo object Demo12 { def main(args: Array[String]): Unit = { val array = (1 to 10).toList val x::y::tail=array println(x,y) } }使用Option类型,可以用来有效的避免空引用(null)异常,当我们返回某些数据的时候,可以返回一个Option来代替
定义
scala中,Option类型表示可选值,这种类型的数据只有两种
Some(x):表示实际的值None:表示没有值使用getOrEles方法,当值是None的时候,可以指定一个默认值示例一
示例说明
定义一个两个数相除的方法,使用Option类型来封装结果然后使用模式匹配来打印结果 不是除零,打印结果除零打印异常错误参考代码
package scala.demo object Demo12 { def dvi(a:Double,b:Double):Option[Double]={ if(b!=0){ Some(a/b) }else{ None } } def main(args: Array[String]): Unit = { val result = dvi(1.0,5) result match { case Some(x)=>println(x) case None=>println("除零异常!") } } }示例二
示例说明
重写上述案例,使用getOrElse方法,当除零时,或者默认值为0参考代码
package scala.demo object Demo12 { def dvi(a:Double,b:Double):Option[Double]={ if(b!=0){ Some(a/b) }else{ None } } def main(args: Array[String]): Unit = { val result = dvi(1,0).getOrElse(0) println(result) } }偏函数可以提供了简洁的语法,可以简化函数的定义,配合集合的函数式编程,让代码更加优雅
定义:
偏函数被包括在花括号内没有match的一组case语句其实就是一个偏函数偏函数是PartialFunction[A,B]的一个实例 - A 代表输入参数列表 - B 代表返回结果类型示例一
示例说明
定义一个偏函数,根据以下方式返回
输入返回值1一2二3三其他其他参考代码
package scala.demo object Demo13 { def main(args: Array[String]): Unit = { val fun1:PartialFunction[Int,String]={ case 1=>"一" case 2=>"二" case 3=>"三" case _=>"其他" } println(fun1(2)) } }示例二
示例说明
定义一个列表,包含1-10的数字请将1-3的数字都转换为[1-3]请将4-8的数字都转换为[4-8]将其他的数字转换为(8-*]参考代码
package scala.demo object Demo14 { def main(args: Array[String]): Unit = { val list = (1 to 10).toList val list1 = list map{ case x if x>=1 && x<=3 =>"[1-3]" case x if x>=4 && x<=8 =>"[4-8]" case x if x>8 =>"(8-*]" } println(list1) } }在scala中.可以很方便的是使用正则表达式来匹配数据
定义:
Regex类
scala中提供了Regex类来定义正则表达式要构造一个Regex对象,直接使用String的r方法就行建议使用三个双引号来表示正则表达式,不然就的对正则中的反斜杠来进行转义 val regEx = """正则表达式""".rfindAllMatchIn方法
使用findAllMatchIn方法可以获取到所有正则匹配到的字符串示例一
示例说明
定义一个正则表达式,来匹配邮箱是否合法合法邮箱测试:qq12344@163.com不合法邮箱测试:qq12344@.com参考代码
package scala.demo object Demo15 { def main(args: Array[String]): Unit = { val r=""".+@.+\..+""".r val eml1 = "qq12344@163.com" val eml2 = "qq12344@.com" if(r.findAllMatchIn(eml1).size!=0){ println(eml1+"合法邮箱") }else { println(eml1 + "不合法邮箱") } if(r.findAllMatchIn(eml2).size!=0){ println(eml2+"合法邮箱") }else{ println(eml2+"不合法邮箱") } } }示例二
示例说明
找出以下列表中的所有不合法的邮箱
"38123845@qq.com", "a1da88123f@gmail.com", "zhansan@163.com", "123afadff.com"参考代码
package scala.demo object Demo16 { def main(args: Array[String]): Unit = { val emlList = List("38123845@qq.com", "a1da88123f@gmail.com", "zhansan@163.com", "123afadff.com") val regex = """.+@.+\..+""".r val list2 = emlList.filter(x=>regex.findAllMatchIn(x).size==0) println(list2) } }示例三
示例说明
有以下邮箱列表 "38123845@qq.com", "a1da88123f@gmail.com", "zhansan@163.com", "123afadff.com" 使用正则表达式进行模式匹配,匹配出来邮箱运营商的名字。例如:邮箱zhansan@163.com,需要将163匹配出来使用括号来匹配分组打印匹配到的邮箱以及运营商参考代码
package scala.demo object Demo17 { def main(args: Array[String]): Unit = { val list =List("38123845@qq.com", "a1da88123f@gmail.com", "zhansan@163.com", "123afadff.com") val regex = """.+@(.+)\..+""".r val list2 = list.map{ case x@regex(company)=>println(s"${x}=>${company}") case x => x + "=>未知" } println(list2) } }