Scala基础语法小结(四)

mac2025-11-15  17

1.样例类

样例类是一种特殊的类,它可以用来快速定义一个用于保存数据的类(类似于Java POJO类)

1.1定义样例类

语法:

case class 样例类名([var/val] 成员变量名1:类型1, 成员变量名2:类型2, 成员变量名3:类型3) 如果要实现某个成员变量可以被修改,可以添加var默认为val,可以省略

1.2定义一个样例类

需求:

定义一个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) } }

1.3可变成员变量

需求:

定义一个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) } }

1.4样例类的方法

1.4.1 apply方法

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) } }
1.4.2 toString方法

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) } }
1.4.3 equals方法

样例类自动实现了equals方法,可以直接使用==比较两个样例类是否相同,即所有的成员变量是否相同 示例

创建一个样例类Person,包含姓名、年龄创建名字年龄分别为"李四", 21的两个对象比较它们是否相等 val lisi1 = CasePerson("李四", 21) val lisi2 = CasePerson("李四", 21) println(lisi1 == lisi2) // 输出:true
1.4.4 hashCode方法

样例类自动实现了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()) } }
1.4.5 copy方法

快速创建一个相同的实例对象,可以使用带名参数指定给成员进行复制

示例

创建名字年龄分别为"李四", 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) } }

2.样例对象

主要作用在两方向:

定义枚举作为没有任何参数的消息进行传递

2.1定义

使用case object 创建样例类对象,样例对象是单例,并且没有主构造器

语法

case object 样例对象名

2.2 定义枚举

需求说明

定义一个性别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) } }

3.模式匹配

scala中有一个非常强大的匹配机制

switch语句类型查询使用模式匹配快速的获取数据

3.1 简单模式匹配

在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) } }

3.2 匹配类型

除了像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表达式中无需使用到匹配到的变量,可以使用下划线来代替

3.3 守卫

在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("未匹配") } } }

3.4 匹配样例类

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("未匹配") } } }

3.5 匹配数组

示例说明

依次修改代码定义以下三个数组 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 ") } } }

3.6 匹配列表

示例说明

依次修改代码定义以下三个列表 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("未匹配") } } }

3.7 匹配元组

示例说明

依次修改代码定义以下两个元组 (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("未匹配") } } }

3.8 变量声明中的模式匹配

定义变量的时候,可以使用模式匹配快速的获取数据

3.8.1 示例| 获取数组中的元素

需求说明

生成包含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) } }
3.8.2 示例| 获取List中的元素

需求说明

生成包含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) } }

4.Option类型

使用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) } }

5.偏函数

偏函数可以提供了简洁的语法,可以简化函数的定义,配合集合的函数式编程,让代码更加优雅

定义:

偏函数被包括在花括号内没有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) } }

6.正则表达式

在scala中.可以很方便的是使用正则表达式来匹配数据

定义:

Regex类

scala中提供了Regex类来定义正则表达式要构造一个Regex对象,直接使用String的r方法就行建议使用三个双引号来表示正则表达式,不然就的对正则中的反斜杠来进行转义 val regEx = """正则表达式""".r

findAllMatchIn方法

使用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) } }
最新回复(0)