Java中的switch-case–了解即可-★
只能按顺序匹配简单的数据类型和表达式(支持:byte、short、int、char、String、枚举,不支持long)
相对而言,Scala中的模式匹配math-case的功能则要强大得多,几乎可以在match中使用任何类型、应用到更多场合
并且Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配。
package cn. hanjiaxiaozhi. casedemo;
public class Case_Java {
public static void main( String [ ] args) {
int day = 6 ;
if ( day <= 1 && day <= 5 ) {
System. out. println( "今天是工作日" ) ;
} else {
System. out. println( "今天是周末~休息" ) ;
}
switch ( day) {
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
System. out. println( "今天是工作日" ) ;
break;
default:
System. out. println( "今天是周末~休息" ) ;
}
}
}
Scala中的模式匹配-★★★
注意:
case语句中不需要使用break语句
case_ 相当于Java中的default
只需要掌握前3个,其他的了解
package cn. hanjiaxiaozhi. casedemo
import scala. util. Random
object Case_Scala {
def main( args: Array[ String ] ) : Unit = {
println( "===============匹配字符串/数字=============" )
val arr1 = Array( "hadoop" , "zookeeper" , "spark" , "flink" )
val index: Int = Random. nextInt( arr1. length)
val str: String = arr1( index)
println( str)
str match {
case "hadoop" => println( "大数据存储计算框架" )
case "zookeeper" => println( "分布式协调服务框架" )
case _ => println( "大数据计算框架" )
}
println( "===============匹配类型=============" )
val arr2 = Array( "hello" , 1 , 2.0 , Case_Scala)
val value = arr2( Random. nextInt( 4 ) )
println( value)
value match {
case s: String => println( "匹配上String:" + s)
case i: Int => println( "匹配上Int:" + i)
case d: Double if ( d > 0 ) => println( "匹配上大于0的Double:" + d)
case o: Case_Scala. type => println( "匹配上了Case_Scala-object:" + o)
case _ => println( "其他" )
}
println( "===============匹配集合=============" )
val arr3 = Array( 0 , 3 , 5 )
arr3 match {
case Array( 0 , x, y) => println( x + " " + y)
case Array( 0 ) => println( "only 0" )
case Array( 0 , _* ) => println( "0 ..." )
case _ => println( "something else" )
}
val li = List( 3 , - 1 )
li 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" )
}
println( "***变量声明中隐藏的模式匹配***" )
val ( x, y) = ( 1 , 2 )
println( x)
println( y)
val ( q, r) = BigInt( 10 ) / % 3
println( q)
println( r)
val arr4 = Array( 1 , 7 , 2 , 9 )
val Array( first, second, _* ) = arr4
println( first, second)
println( "***其他语法中混合使用模式匹配***" )
val kvs = Map( "k1" - > "v1" , "k2" - > "v2" , "k3" - > "v3" )
for ( ( k, v) <- kvs) {
println( k + ":" + v)
}
println( "***6.函数式操作中的模式匹配***" )
kvs. foreach {
case ( k, v) => println( k, v)
}
println( "***7.匹配样例类***" )
val arr = Array( CheckTimeOutTask, HeartBeat( 10 ) , SubmitTask( "001" , "task-001" ) , StopTask)
val obj = arr( Random. nextInt( arr. length) )
println( obj)
obj match {
case SubmitTask( id, name) => println( s"$id, $name" )
case HeartBeat( time) => println( time)
case CheckTimeOutTask => println( "check" )
case StopTask => println( "stop" )
}
}
}
case class SubmitTask( id: String , name: String )
case class HeartBeat( time: Long )
case object CheckTimeOutTask
case object StopTask
补充:Option类型
在Scala中为单个值提供了对象的包装器,Option类型用样例类来表示可能存在或也可能不存在的值
Option的子类有Some和None,Some包装了某个值,None表示没有值
通过Option的使用,避免了使用null、空字符串等方式来表示缺少某个值的做法
package cn. hanjiaxiaozhi. case_demo
object OptionDemo {
def main( args: Array[ String ] ) {
val map = Map( "a" - > 1 , "b" - > 2 )
val v = map. get( "c" ) match {
case Some( i) => i
case None => 0
}
println( v)
val v2: Int = map. getOrElse( "a" , 0 )
println( v2)
}
}
补充:异常处理
说明
受检异常在编译期被检查,在Java中必须在方法上声明该方法可能会发生的受检异常
Scala的异常的工作机制和Java一样,但是Scala没有checked受检异常,你不需要声明函数或者方法可能会抛出某种异常。
抛出异常:
用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。
throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方。
捕捉异常:
在catch的代码里,使用一系列case子句(借用了模式匹配的思想来做异常的匹配)
异常捕捉的机制与其他语言中一样,如果有异常发生,catch字句是按次序捕捉的。因此,在catch字句中,越具体的异常越要靠前,越普遍的异常越靠后。
如果抛出的异常不在catch字句中,该异常则无法处理,会被升级到调用者处。
finally字句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,一般用于对象的清理工作。
package cn. hanjiaxiaozhi. case_demo
object ExceptionDemo {
def main( args: Array[ String ] ) : Unit = {
try {
println( divider( 10 , 0 ) )
} catch {
case ex: Exception => println( "捕获了异常:" + ex)
} finally {
println( "释放资源" )
}
println( "处理了异常,代码继续往下执行" )
}
def divider( x: Int , y: Int ) : Float = {
if ( y == 0 ) throw new Exception( "0作为了除数" )
else x / y
}
}
扩展:偏函数
被包在花括号内没有match的一组case语句是一个偏函数
偏函数是PartialFunction[A, B]的一个实例,A代表参数类型,B代表返回类型,常用作输入模式匹配
偏函数最大的特点就是它只接受和处理其参数定义域的一个子集
package cn. hanjiaxiaozhi. case_demo
object PartialFuncDemo {
def func1( num: String ) : Int = {
num match {
case "one" => 1
case "two" => 2
case _ => - 1
}
}
val func2: PartialFunction[ String , Int ] = {
case "one" => 1
case "two" => 2
case _ => - 1
}
def main( args: Array[ String ] ) {
println( func1( "one" ) )
println( func2( "one" ) )
val list = List( 1 , 6 , 8 )
val list2 = list. map{
case x if x >= 1 && x <= 5 => "工作日"
case x if x >= 6 && x <= 7 => "休息日"
case x if x > 7 => "不认识"
}
println( list2)
}
}
扩展:提取器
之前我们学习过了,实现一个类的伴生对象中的apply方法,可以用类名来快速构建一个对象
伴生对象中,还有一个unapply方法。与apply相反,unapply是将该类的对象,拆解为一个个的元素,常用于模式匹配
样例类中自动提供apply方法和unapply方法
class Student( var name: String , var age: Int )
object Student {
def apply( name: String , age: Int ) = {
println( "apply方法被调用" )
new Student( name, age)
}
def unapply( s: Student) = {
println( "unapply方法被调用" )
if ( s != null ) {
Some( s. name, s. age)
}
else {
None
}
}
}
object TestStudent {
def main( args: Array[ String ] ) : Unit = {
val s = Student( "张三" , 20 )
s match {
case Student( name, age) => println( s"${name} => ${age}" )
}
}
}