Scala高级用法 1

简介: Scala高级用法

1 样例类

样例类是一种特殊类,它可以用来快速定义一个用于保存数据的类(类似于Java POJO类),而且它会自动生成apply方法,允许我们快速地创建样例类实例对象。后面,在并发编程和spark、flink这些框架也都会经常使用它。

1.1 定义样例类

语法结构:

case class 样例类名(成员变量名1:类型1, 成员变量名2:类型2, 成员变量名3:类型3)

示例1:

// 定义一个样例类
// 样例类有两个成员name、age
case class CasePerson(name:String, age:Int)
// 使用var指定成员变量是可变的
case class CaseStudent(var name:String, var age:Int)
object CaseClassDemo {
  def main(args: Array[String]): Unit = {
    // 1. 使用new创建实例
    val zhagnsan = new CasePerson("张三", 20)
    println(zhagnsan)
    // 2. 使用类名直接创建实例
    val lisi = CasePerson("李四", 21)
    println(lisi)
    // 3. 样例类默认的成员变量都是val的,除非手动指定变量为var类型
    //lisi.age = 22  // 编译错误!age默认为val类型
    val xiaohong = CaseStudent("小红", 23)
    xiaohong.age = 24
    println(xiaohong)
  }
}

1.2 样例类方法


toString方法

toString返回:样例类名称(成员变量1, 成员变量2, 成员变量3…)

case class CasePerson(name:String, age:Int)
object CaseClassDemo {
  def main(args: Array[String]): Unit = {
    val lisi = CasePerson("李四", 21)
    println(lisi.toString)
    // 输出:CasePerson(李四,21)
  }
}

equals方法

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

val lisi1 = CasePerson("李四", 21)
val lisi2 = CasePerson("李四", 21)
println(lisi1 == lisi2)
// 输出:true

hashCode方法

样例类自动实现了hashCode方法,如果所有成员变量的值相同,则hash值相同,只要有一个不一样,则hash值不一样。

val lisi1 = CasePerson("李四", 21)
val lisi2 = CasePerson("李四", 22)
println(lisi1.hashCode())
println(lisi2.hashCode())

copy方法

样例类实现了copy方法,可以快速创建一个相同的实例对象,可以使用带名参数指定给成员进行重新赋值。

val lisi1 = CasePerson("李四", 21)
val wangwu = lisi1.copy(name="王五")
println(wangwu)

1.3 样例对象


使用case object可以创建样例对象。样例对象是单例的,而且它没有主构造器。样例对象是可序列化的。格式:

case object 样例对象名

它主要用在两个地方:

  1. 定义枚举
  2. 作为没有任何参数的消息传递(后面Akka编程会讲到)

示例:定义枚举

trait Sex /*定义一个性别特质*/
case object Male extends Sex    // 定义一个样例对象并实现了Sex特质
case object Female extends Sex    
case class Person(name:String, sex:Sex)
object CaseClassDemo {
  def main(args: Array[String]): Unit = {
    val zhangsan = Person("张三", Male)
    println(zhangsan)
  }
}

示例:定义消息

case class StartSpeakingMessage(textToSpeak: String)
// 消息如果没有任何参数,就可以定义为样例对象
case object StopSpeakingMessage
case object PauseSpeakingMessage
case object ResumeSpeakingMessage

样例类可以使用**类名(参数1, 参数2…)**快速创建实例对象

定义样例类成员变量时,可以指定var类型,表示可变。默认是不可变的

样例类自动生成了toString、equals、hashCode、copy方法

样例对象没有主构造器,可以使用样例对象来创建枚举、或者标识一类没有任何数据的消息

2 模式匹配

scala中有一个非常强大的模式匹配机制,可以应用在很多场景:

  • switch语句
  • 类型查询
  • 以及快速获取数据

2.1 简单匹配

在Java中,有switch关键字,可以简化if条件判断语句。在scala中,可以使用match表达式替代。

语法结构:

变量 match {
    case "常量1" => 表达式1
    case "常量2" => 表达式2
    case "常量3" => 表达式3
    case _ => 表达式4    // 默认匹配
}

示例1:

println("请输出一个词:")
// StdIn.readLine表示从控制台读取一行文本
val name = StdIn.readLine()
val result = name match {
    case "hadoop" => s"$name:大数据分布式存储和计算框架"
    case "zookeeper" => s"$name:大数据分布式协调服务框架"
    case "spark" => s"$name:大数据分布式内存计算框架..."
    case _ => s"未匹配到$name"
}
println(result)

match表达式是有返回值的,可以将match表达式对其他的变量进行赋值

2.2 守卫


在Java中,只能简单地添加多个case标签,例如:要匹配0-7,就需要写出来8个case语句。例如:

int a = 0;
switch(a) {
    case 0: a += 1;
    case 1: a += 1;
    case 2: a += 1;
    case 3: a += 1;
    case 4: a += 2;
    case 5: a += 2;
    case 6: a += 2;
    case 7: a += 2;
    default: a = 0;
}

在scala中,可以使用守卫来简化上述代码——也就是在case语句中添加if条件判断

示例:

println("请输入一个数字:")
var a = StdIn.readInt()
a match {
    case a1 if a >= 0 && a <= 3 => a += 1
    case a2 if a > 3 && a < 8 => a += 2
    case _ => a = 0
}
println(a)

2.3 匹配类型


match表达式还可以进行类型匹配。

语法格式如下:

变量 match {
    case 类型1变量名: 类型1 => 表达式1
    case 类型2变量名: 类型2 => 表达式2
    case 类型3变量名: 类型3 => 表达式3
    ...
    case _ => 表达式4
}

示例:

    // stripMargin表示删除前面的竖线,这样看起来会显得比较整齐
    val prompt =
      """
        |0:字符串类型
        |1:整形
        |2:浮点型
        |3:Person对象类型
        |
        |请选择:
      """.stripMargin
    println(prompt)
    val select = StdIn.readInt()
    val selectedValue = select match {
      case 0 => "hello"
      case 1 => 1
      case 2 => 2.0
      case _ => new Person("张三")
    }
    selectedValue match {
      case x: Int => println("Int " + x)
      case y: Double => println("Double " + y)
      case z: String => println("String " + z)
      case _ => throw new Exception("not match exception")
    }

2.4 匹配集合


匹配数组

示例:

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("something else")
}

匹配列表

示例:

val lst = List(3, -1)
lst match {
    case 0 :: Nil => println("only 0")
    case x :: y :: Nil => println(s"x: $x y: $y")
    case 0 :: tail => println("0 ...")
    case _ => println("something else")
}

匹配元组

示例:

val tup = (1, 3, 7)
tup match {
    case (1, x, y) => println(s"1, $x , $y")
    case (_, z, 5) => println(z)
    case  _ => println("else")
}

2.5 变量声明中的模式匹配


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

示例:获取数组中的元素

val arr = Range(0, 10).toArray
arr.foreach(println(_))
// 使用模式匹配,获取第二个、第三个、第四个元素的值
val Array(_, x, y, z, _*) = arr
println(s"x=$x, y=$y, z=$z, ")

示例:获取List中的数据

val list = Range(0, 10).toList
// 匹配列表的第一个、第二个元素的值
val x::y::tail = list
println(s"x=$x, y=$y")

2.6 匹配样例类


scala可以使用模式匹配来匹配样例类,从而可以快速获取样例类中的成员数据。后续,我们在开发Akka案例时,还会用到。

示例:

// 定义样例类
case class SubmitTask(id: String, name: String)
case class HeartBeat(time: Long)
case object CheckTimeOutTask
val msg1 = SubmitTask("001", "task-001")
val msg2 = HeartBeat(1000)
val msg3 = CheckTimeOutTask
val list = List(msg1, msg2, msg3)
list(2) match {
    case SubmitTask(id, name) => println(s"id=$id, name=$name")
    case HeartBeat(time) => println(s"time=$time")
    case CheckTimeOutTask => println("检查超时")
}

示例:可以使用@符号分隔case语句,用来获取用于匹配的整个示例对象

list(0) match {
    // obj表示获取用于匹配的样例对象,而id,name表示获取样例中的元素
    case  obj @ SubmitTask(id, name) => println(s"id=$id, name=$name");println(s"样例类:$obj")
    case HeartBeat(time) => println(s"time=$time")
    case CheckTimeOutTask => println("检查超时")
}


目录
相关文章
|
3月前
|
消息中间件 分布式计算 Java
Scala函数式编程【从基础到高级】
Scala函数式编程【从基础到高级】
|
3月前
|
存储 Scala 索引
scala中常见数据结构的用法
scala中常见数据结构的用法
21 1
|
3月前
|
SQL 分布式计算 Serverless
scala-spark中的groupby、like等的用法
scala-spark中的groupby、like等的用法
94 0
|
11月前
|
前端开发 Java 程序员
Scala高级用法 3
Scala高级用法
32 0
|
11月前
|
Java Scala
Scala高级用法 2
Scala高级用法
35 0
|
Java Scala
Scala的高级用法
Scala的高级用法
|
Java Scala
scala 匿名函数的用法实操
1. => 什么意思 => 匿名函数(Anonymous Functions),表示创建一个函数实例。 比如:(x: Int) => x + 1 和如下JAVA方法表示的含义一样:
107 0
scala之list用法史上最全
Scala 列表类似于数组,它们所有元素的类型都相同,但是它们也有所不同:列表是不可变的,值一旦被定义了就不能改变,其次列表 具有递归的结构(也就是链接表结构)而数组不是 下面是list的常用方法,当然了这不是所有的.但都是最常用的.具体看下面的demo.具体可以看代码里面的注释
|
2月前
|
分布式计算 资源调度 Java
Scala+Spark+Hadoop+IDEA实现WordCount单词计数,上传并执行任务(简单实例-下)
Scala+Spark+Hadoop+IDEA实现WordCount单词计数,上传并执行任务(简单实例-下)
34 0
|
2月前
|
分布式计算 Hadoop Scala
Scala +Spark+Hadoop+Zookeeper+IDEA实现WordCount单词计数(简单实例-上)
Scala +Spark+Hadoop+Zookeeper+IDEA实现WordCount单词计数(简单实例-上)
27 0