scala--pattern matching-★★★

Switch-case in Java-just understand-★

  • Only simple data types and expressions can be matched in order (support: byte, short, int, char, String, enumeration, long is not supported)
  • Relatively speaking, the function of pattern matching math-case in Scala is much more powerful. Almost any type can be used in match and applied to more occasions.
  • And Scala also provides sample classes, optimized for pattern matching, and can be matched quickly.
package cn.hanjiaxiaozhi.casedemo;

/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 11:30
 * Desc 演示java中的switch
 */
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
        switch (day){
    
    
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
                System.out.println("今天是工作日");
                break;
            default:
                System.out.println("今天是周末~休息");
        }

        //Java之后的switch~case可以完成类似于if-else的条件判断
        //但是有限制:switch (参数),只支持:byte,short,int,String,枚举,不支持其他的复杂类型,甚至是Long
        //而Scala中的模式匹配很强大,支持一切~
        //当然Java后续的新版本也开始慢慢学习Scala
    }
}

Pattern matching in Scala-★★★

  • note:
    • No need to use break statement in case statement
    • case_ is equivalent to default in Java
  • Only need to master the first 3, understand the others
package cn.hanjiaxiaozhi.casedemo

import scala.util.Random

/**
 * Author hanjiaxiaozhi
 * Date 2020/7/17 11:38
 * Desc 演示Scala中的模式匹配--类似Java中的switch-case,但是比Java的要强大
 */
object Case_Scala {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //1.匹配字符串/数字...--掌握
    println("===============匹配字符串/数字=============")
    val arr1 = Array("hadoop", "zookeeper", "spark", "flink")
    val index: Int = Random.nextInt(arr1.length) //获取[0~arr1.length)的随机数
    val str: String = arr1(index)
    println(str)
    str match {
    
    
      case "hadoop" => println("大数据存储计算框架")
      case "zookeeper" => println("分布式协调服务框架")
      case _ => println("大数据计算框架") //相当于default
    }

    //2.匹配类型--掌握
    println("===============匹配类型=============")
    //Array(字符串, Int, Double, object)
    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("其他")
    }


    //3.匹配集合(可以一次匹配单个变量,还支持各种符号)--掌握,符号不用记
    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") //x: 3 y: -1
      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") //1, 3 , 7
      case (_, z, 5) => println(z)
      case _ => println("else")
    }

    //4.变量声明中隐藏的模式匹配---了解
    println("***变量声明中隐藏的模式匹配***")
    val (x, y) = (1, 2) //表示x = 1,y=2
    println(x) //1
    println(y) //2
    val (q, r) = BigInt(10) /% 3 //10先除以3结果3给q, 10模3结果1给r
    println(q) //3
    println(r) //1
    val arr4 = Array(1, 7, 2, 9)
    val Array(first, second, _*) = arr4 //表示不arr4中的第一个元素给first,第二个元素给second
    println(first, second) //(1,7)


    //5.其他语法中混合使用模式匹配--了解
    println("***其他语法中混合使用模式匹配***")
    val kvs = Map("k1" -> "v1", "k2" -> "v2", "k3" -> "v3")
    for ((k, v) <- kvs) {
    
     //也是模式匹配,只不过不是显式的match-case
      println(k + ":" + v)
    }

    //6.函数式操作中的模式匹配--了解
    println("***6.函数式操作中的模式匹配***")
    kvs.foreach {
    
    
      case (k, v) => println(k, v)
    }


    //7.匹配样例类==后面案例的时候单独使用讲解--先了解
    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) //样例类--可以根据他创建对象 如: SubmitTask(1, "task1")
case class HeartBeat(time: Long) //样例类
case object CheckTimeOutTask //样例对象,就是一个对象,没有属性 --了解
case object StopTask //样例对象,就是一个对象,没有属性--了解

Supplement: Option type

  • In Scala, an object wrapper is provided for a single value, and the Option type uses a sample class to represent values ​​that may or may not exist
  • The subclasses of Option are Some and None, Some wraps a certain value, and None means no value
  • Through the use of Option, it avoids the use of null, empty string, etc. to indicate the lack of a value
package cn.hanjiaxiaozhi.case_demo

object OptionDemo {
    
    
  def main(args: Array[String]) {
    
    
    val map = Map("a" -> 1, "b" -> 2)

    //使用模式匹配:从map中根据k获取v,如果获取到了直接返回,没获取到返回默认值0
    val v = map.get("c") match {
    
    
      //Option是一个装有1个或0个元素的容器
      //Some和None都是Option的子类
      case Some(i) => i //Some里面有1个元素
      case None => 0 //None里面有0个元素
    }
    println(v)

    //使用getOrElse
    val v2: Int = map.getOrElse("a",0)
    println(v2)
  }
}

Supplement: exception handling

  • Description
    • Checked exceptions are checked at compile time. In Java, the checked exceptions that may occur in the method must be declared on the method.
    • The working mechanism of Scala's exceptions is the same as that of Java, but Scala does not have checked exceptions. You don't need to declare functions or methods that may throw some kind of exceptions.
  • Throw an exception:
    • Use the throw keyword to throw an exception object. All exceptions are subtypes of Throwable.
    • The throw expression has a type, which is Nothing. Because Nothing is a subtype of all types, the throw expression can be used where a type is needed.
  • Catch the exception:
    • In the catch code, a series of case clauses are used (borrowing the idea of ​​pattern matching to do abnormal matching)
    • The mechanism of exception capture is the same as in other languages. If an exception occurs, the catch words are captured in order. Therefore, in the catch sentence, the more specific anomaly, the more advanced it is, and the more common anomaly, the more advanced it is.
    • If the thrown exception is not in the catch clause, the exception cannot be handled and will be escalated to the caller.
    • The finally word is used to perform steps that need to be performed regardless of whether it is normal processing or when an exception occurs. It is generally used for cleaning up the object.
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
  }
}

Extension: Partial function

  • A set of case statements without a match enclosed in curly braces is a partial function
  • Partial function is an instance of PartialFunction[A, B], A represents the parameter type, B represents the return type, and is often used for input pattern matching
  • The biggest feature of a partial function is that it only accepts and processes a subset of its parameter domain.
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]) {
    
    
    //1.调用方法
    println(func1("one"))

    //2.调用偏函数
    println(func2("one"))

    val list = List(1,6,8)
    //3.传入偏函数
    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)
  }
}

Extension: Extractor

  • We have learned before, to implement the apply method in the companion object of a class, you can use the class name to quickly build an object
  • There is also an unapply method in the companion object. Contrary to apply, unapply is to disassemble the object of this class into individual elements, which is often used for pattern matching
  • The apply method and unapply method are automatically provided in the sample class
    Insert picture description here
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 = {
    
    
    //调用apply
    val s = Student("张三", 20)

    //调用unapply
    s match {
    
    
      case Student(name, age) => println(s"${name} => ${age}")
    }
  }
}

Guess you like

Origin blog.csdn.net/qq_46893497/article/details/114043633