• scala03


    1. 样例类

      样例类是一种特殊的类,它可以用来快速定义一个保存数据的类,类似于java中的pojo类。

    • 如果要实现成员变量可以被修改需要添加var
    • 默认是val,可以省略
    object Demo01 {
    
      //变量的默认修饰符不写就是:val
      case class Person(name: String, var age: Int)
    
      def main(args: Array[String]): Unit = {
        //样例对象不用new,说明重写了apply
        val p = Person("刘德华", 54)
        //重写了toString方法
        println(p)
        //验证样例类的默认修饰符是val
        //p.age=24
        println("_" * 30)
        //演示样例类额equals方法,因为样例类的底层已经重写了
    
    
        val p1 = Person("周星驰", 46)
        val p2 = Person("周星驰", 46)
        println(p1 == p2) //true比较的是属性值
        println(p1.eq(p2)) //false比较的是地址值
    
        println("_" * 30)
    
        //演示样例类对象的hash值
        //相同对象hash肯定相同,不同对象的hash一般不同,但是可能相同。
        println(p1.hashCode())
        println(p2.hashCode())
        println("_" * 30)
        //补充内容,内容不同,但是hash值相同的特例
        println("重地".hashCode)
        println("通话".hashCode)
        println("_" * 30)
    
        println("儿女".hashCode)
        println("农丰".hashCode)
        println("_" * 30)
    
        //测试copy方法
        val p3 = Person("陈一发", 27)
        p3.copy("刘一发", 26) //copy相当重新new了一个对象
    
      }
    
    }
    View Code

    2. 样例对象

      使用case object可以创建样例对象,样例对象是单例的,而且他没有主构造器

    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)
      }
    }
    View Code

    3. 模式匹配

    A:简单模式匹配

    package com.itheima.moshipipei
    
    import scala.io.StdIn
    
    //模式匹配之简单匹配
    object Demo01 {
    
      def main(args: Array[String]): Unit = {
        //录入字符串并接收
        print("请输入字符串")
        var str = StdIn.readLine()
    
    
        //判断字符串是否是指定结果,并接收结果
        val result: String = str match {
          case "hadoop" => "大数据分布式存储和计算框架"
          case "zookeeper" => "大数据分布式协调服务框架"
          case "spark" => "大数据分布式计算框架"
          case _ => "未匹配"
        }
        //打印结果
        println(result)
    
        println("-" * 30)
    
        str match {
          case "hadoop" => println("大数据分布式存储和计算框架")
          case "zookeeper" => println("大数据分布式协调服务框架")
          case "spark" => println("大数据分布式计算框架")
          case _ => println("未匹配")
        }
    
    
      }
    
    }
    View Code

    B:匹配类型

    package com.itheima.moshipipei
    
    //模式匹配之匹配类型
    object Demo02 {
    
      def main(args: Array[String]): Unit = {
    
        val a:Any="hadoop"
    
        val b:Any=1.0
    
        a match {
          case x:String =>println(s"${x}是String类型数据")
          case x:Double =>println(s"${x}是Double类型数据")
          case x:Int =>println(s"${x}是Int类型数据")
          case _=> println("未匹配")
        }
    
        println("-"*30)
    
        //如果case在校验的时候,没有被使用,则可以用_替代
        b match {
          case _:String =>println("String")
          case _:Double =>println("Double")
          case _:Int =>println("Int")
          case _=> println("未匹配")
        }
    
    
      }
    
    }
    View Code

    C:守卫

    package com.itheima.moshipipei
    
    import scala.io.StdIn
    
    object Demo03 {
    
      def main(args: Array[String]): Unit = {
        println("请录入一个整数:")
        var num=StdIn.readInt()
    
        num match {
          case a if a>0 && a<=3  =>println("a[0-3]")
          case a if a>=4 && a<=8  =>println("a[4-8]")
          case _=>println("未匹配")
        }
      }
    
    }
    View Code

    D:匹配样例类

    package com.itheima.moshipipei
    
    //匹配样例类
    //注意:通过match进行匹配的时候,要匹配的对象必须声明成any类型
    object Demo06 {
    
      case class Customer(var name: String, var age: Int)
    
      case class Order(id: Int)
    
    
      def main(args: Array[String]): Unit = {
    
    
        val c: Any = Customer("刘德华", 73)
        val o: Any = Order(123)
    
        c match {
          case Customer(x, y) => println(s"Customer:${x},${y}")
          case Order(x) => println("Order")
          case _ => println("未匹配")
        }
    
      }
    
    }
    View Code

    E:匹配数组

    package com.itheima.moshipipei
    
    object Demo04 {
    
      def main(args: Array[String]): Unit = {
        //定义三个数组
        val arr1 = Array(1, 2, 3)
    
        val arr2 = Array(0)
    
        val arr3 = Array(0, 1, 2, 3, 4, 5)
    
        //通过模式匹配找到合适的数组
    
        arr1 match {
          //长度为3,首元素为1,后两位无所谓
          case Array(1, x, y) => println(s"匹配长度为3,首元素是1,后二${x},${y}")
          //匹配只有一个0元素的数组
          case Array(0) => println("只有一个元素0")
          //匹配第一个元素是1,后面元素无所谓
          case Array(1, _*) => println("第一个元素是1,后面元素无所谓")
          //其他校验
          case _ => println("未匹配")
        }
      }
    
    }
    View Code

    F:匹配列表

    package com.itheima.moshipipei
    
    object Demo05 {
    
    
      def main(args: Array[String]): Unit = {
        val list1 = List(0)
        val list2 = List(0, 1, 2, 3, 4, 5)
        val list3 = List(1, 2)
    
        //用List匹配
        list1 match {
          case List(0) => println("匹配只有一个元素0")
          case List(0, _*) => println("0___*")
          case List(x, y) => println("x,y")
          case _ => println("未匹配")
        }
    
        //关键字优化
        list2 match {
          case Nil => println("匹配只有一个元素0")
          case 0 :: tail => println("0___*")
          case x :: y :: Nil => println("x,y")
          case _ => println("未匹配")
        }
    
      }
    
    }
    View Code

    G:匹配元组

    package com.itheima.moshipipei
    
    //匹配元组
    object Demo07 {
    
      def main(args: Array[String]): Unit = {
        val a = (1, 2, 3)
        val b = (4, 5, 6)
    
        a match {
          case (1, x, y) => println("长度为3,1开头后两个元素无所谓")
          case (x, y, 5) => println("匹配长度为3,以5结尾,前两个元素无所谓")
          case _ => println("未匹配")
        }
      }
    
    }
    View Code

    H:变量声明中的模式匹配

    val array = (1 to 10).toArray
    val Array(_, x, y, z, _*) = array
    println(x, y, z)
    
    
    val list = (1 to 10).toList
    val x :: y :: tail = list
    println(x, y)
    View Code

    4. Option类型

    • Some(x):表示实际的值
    • None:表示没有值
    • getorElse():当值为None的时候可以指定一个默认值
    package com.itheima.option
    
    object Demo01 {
    
      def div(a: Int, b: Int) = {
        if (b == 0) {
          None //除数为0没有结果
        } else {
          Some(a / b) //除数不为0,返回具体结果
        }
      }
    
      def main(args: Array[String]): Unit = {
        var result = div(10, 0)
    
        result match {
          case Some(x) => println(x)
          case None => println("除数不能为0")
        }
    
        println("-" * 30)
        println(result.getOrElse(0))
      }
    
    }
    View Code

    5. 偏函数

    package com.itheima.panhuanshu
    
    object Demo01 {
    
      def main(args: Array[String]): Unit = {
        val ps: PartialFunction[Int, String] = {
          case 1 => "一"
          case 2 => "二"
          case 3 => "三"
          case _ => "其他"
        }
    
        println(ps(1))
    
        println(ps(2))
      }
    
    }
    View Code
    package com.itheima.panhuanshu
    
    object Demo02 {
    
      def main(args: Array[String]): Unit = {
        val list1 = (1 to 10).toList
        //将1-3的数字转换为【1-3】
        var list2 = list1.map {
          case x if x >= 1 && x <= 3 => "[1-3]"
          case x if x >= 4 && x <= 7 => "[4-8]"
          case _ => "[8-*]"
        }
        println(list2)
      }
    }
    View Code

    6. 正则表达式

    package com.itheima.zhengzhe
    
    //案例 正则表达式入门
    object Demo01 {
      def main(args: Array[String]): Unit = {
        val mail = "qq123456@163.com"
    
        /**
          * .表示任意字符
          * +数量词,前面的字符至少出现一次,至多不上限制
          * @  必须出现的
          * 是转义字符
          */
        var regex =
          """.+@.+..+""".r
        if (regex.findAllMatchIn(mail).size != 0) {
          println("合法邮箱")
          print(regex.findAllMatchIn(mail).toList)
        } else {
          println("非法邮箱")
        }
      }
    
    }
    View Code
    package com.itheima.zhengzhe
    
    object Demo02 {
    
      def main(args: Array[String]): Unit = {
    
        val emlList = List("38123845@qq.com", "a1da88123f@gmail.com", "zhansan@163.com", "123afadff.com")
    
        val regex=""".+@.+..+""".r
        val list=emlList.filter(x=>regex.findAllMatchIn(x).size==0)
    
        println(list)
      }
    
    }
    View Code
    package com.itheima.zhengzhe
    
    object Demo03 {
    
      def main(args: Array[String]): Unit = {
        val regex = """.+@(.+)..+""".r
    
        val emlList = List("38123845@qq.com", "a1da88123f@gmail.com", "zhansan@163.com", "123afadff.com")
    
        //根据模式匹配获取所有合法的邮箱及其对应的运营商
        val result = emlList.map {
          //表示emlList中的元素
          //company表示正则表达式括号括起来的内容
          case email@regex(company) => s"邮箱${email}对应的公司是:${company}"
          case email => s"${email}未匹配"
        }
    
        println(result)
    
        val re = emlList.map {
          //表示emlList中的元素
          //company表示正则表达式括号括起来的内容
          case email@regex(company) => email -> s"${company}"
          case email => email -> "未匹配"
        }
    
        println(re)
      }
    
    }
    View Code

    7. 异常处理

    package com.itheima.yichang
    //演示try catch
    object Demo01 {
      def main(args: Array[String]): Unit = {
          try {
            val i = 10 / 0
          } catch {
            case ex:Exception =>ex.printStackTrace()
          }
    
    
        println("你好啊")
      }
    
    }
    View Code

    8. 提取器

    • 样例类中自动实现了apply,unapply方法,支持模式匹配。
    • 不是所有类的类可以进行这样的模式匹配
    • 要支持模式匹配必须要实现一个提取器
    package com.itheima.tiquqi
    
    object Demo02 {
    
      case class Customer(name: String, age: Int)
    
      case class Person(id: Int)
    
      def main(args: Array[String]): Unit = {
        val c: Any = Customer("刘德华", 46)
        val p: Any = Person(1)
    
        p match {
          case Person(id) => println("这是人")
          case Customer(name, age) => println("这是顾客")
        }
      }
    
    }
    View Code

    package com.itheima.tiquqi
    
    
    //演示:scala中的提取器
    object Demo01 {
    
      class Student(var name:String,var age:Int)
    
      object Student{
        def  apply(name:String,age:Int)=new Student(name,age)
    
        def unapply(s: Student): Option[(String, Int)] = {
          if(s!=null)
            Some(s.name,s.age)
          else
            None
        }
      }
    
    
      def main(args: Array[String]): Unit = {
        val s=new Student("刘德华",12)//普通方式创建对象
    
        val s1=Student("周",3)
    
        //通过提取器获取对象中的方法
        val result=Student.unapply(s1)
        println(result)
    
      }
    
    }
    View Code

     9. 泛型

    A:泛型方法

    package com.itheima.fanxing
    
    //泛指某种数据的类型
    //细节:泛型方法在调用方法的时候,明确具体数据类型
    object Demo01 {
    
      //def getMiddleEle(arr:Array[Any])=arr(arr.length/2)
      def getMiddleEle[T](arr: Array[T]) = arr(arr.length / 2)
    
      def main(args: Array[String]): Unit = {
        println(getMiddleEle(Array(1, 2, 3, 4, 5)))
      }
    
    }
    View Code

    B:定义泛型类

    • 泛型类是在创建对象的时候明确具体的数据类型
    package com.itheima.fanxing
    
    
    //泛型类:在创建对象的时候,明确数据类型
    object Demo02 {
      case class Pair[T](name:T,age:T)
      def main(args: Array[String]): Unit = {
        val pairList = List(
          Pair("Hadoop", "Storm"),
          Pair("Hadoop", 2008),
          Pair(1.0, 2.0),
          Pair("Hadoop", Some(1.9))
        )
    
        println(pairList)
      }
    
    }
    View Code

    C:上下界

    • 使用<:类型名表示给类型添加一个上界,表示泛型参数必须是从该类(或本身)继承
    • 使用>:类型名表示给类型添加一个下界,表示泛型参数必须是某个类的父类
    • 如果类既有上界又有下界,下界写在前面,上界写在后面

    上界

    package com.itheima.fanxing
    
    //演示泛型上界
    object Demo03 {
    
      class Person
      class Student extends Person
    
      def  demo[T<:Person](arr:Array[T])=println(arr)
    
      def main(args: Array[String]): Unit = {
        //demo(Array(1,2,3))报错
        demo(Array(new Person))
        //demo(Array(new Student))报错
      }
    
    }
    View Code

    下界

    package com.itheima.fanxing
    //演示下界
    object Demo04 {
      class Person
    
      class Policeman extends Person
    
      class Superman extends Policeman
    
      def demo[T>:Policeman](array:Array[T])=println(array)
    
      def main(args: Array[String]): Unit = {
        demo(Array(new Person))
        demo(Array(new Policeman))
        //demo(Array(new Superman))报错
      }
    
    }
    View Code

    D:协变、逆变、非变

    非变

    • class Pair[T]{}
    • 默认泛型是非变的
    • 类型B是A的子类型,Pair[B]和Pair[A]没有任何从属关系
    • java是一样的

    协变

    • class Pair[+T]
    • 类型B是类型A的子类,Pair[B]可以认为是Pair[A]的子类型
    • 参数化类型的方向和类型的方向是一致的

    逆变

    • class Pair[-T]
    • 参数B是A的子类型,Pair[A]反过来可以认为是Pair[B]的子类型
    • 参数化类型的方向和类型的方向是相反的
    package com.itheima.fanxing
    
    //演示:非变
    object Demo05 {
    
      class Super
    
      class Sub extends Super
    
      class Temp1[Sub]
    
      class Temp2[+Sub]
    
      class Temp3[-Sub]
    
      def main(args: Array[String]): Unit = {
        val a: Temp1[Sub] = new Demo05() = new Temp1[Sub]
        //编译报错
        //非变
        //val b:Temp1[Super]=a
    
        //协变
        val c: Temp2[Sub] = new Temp2[Sub]
        val d: Temp2[Super] = c
    
        //逆变
        val e: Temp3[Super] = new Temp3[Super]
        val f: Temp3[Sub] = e
    
      }
    }
    View Code

    10. Actor

    A:Java并发编程的问题

      在java并发编程中,每个对象都有一个逻辑监视器(monitor),可以用来控制对象的多线程访问。我们添加sychronized关键字来标记,需要进行同步加锁访问,这样通过加锁的机制来确保同一时间只有一个线程访问共享数据,但是这种方式存在资源竞争,以及死锁问题,程序越大越麻烦。

    B:Actor并发编程模型

      Actor编程是一种基于事件模型的并发机制,一种不共享数据,依赖消息传递的一种并发编程模式,有效避免资源争夺,死锁等情况。

     C:创建Actor

      • 定义class或者object继承Actor特质
      • 重写act方法
      • 调用Actor的start方法执行Actor
      • 类似于java线程,每个Actor是并发执行的
    import scala.actors.Actor
    
    //actor 并发编程入门  通过class 创建actor
    //用class还是object来创建object的依据是,该Actor对象是否创建多个。单个用object,多个用class
    object Demo01 {
    
      //创建actor1打印1-10的数字
      class Actor1 extends Actor{
        override def act(): Unit = for(i<- 1 to 10) println("actor1----"+i)
      }
    
      class Actor2 extends Actor{
        override def act(): Unit = for(i<- 11 to 20) println("actor2----"+i)
      }
    
      def main(args: Array[String]): Unit = {
        new Actor1().start()
        new Actor2().start()
      }
    
    }
    View Code
      1. 调用start方法启动Actor
      2. 自动执行act方法
      3. 向Actor发送消息
      4. act方法执行完成后,程序会自动调用exit()方法

     D:发送消息/接受消息

    发送消息

     如果要给actor1发送一个异步字符串消息:actor ! “您好”

    接收消息

    Actor中receive方法来接收消息,需要给receive传入一个偏函数

    receive方法直接收一次消息

    object Demo04 {
    
    
      //创建Sender
      object ActorSender extends Actor{
        override def act(): Unit = {
          while (true){
    
            ActorReciever ! "你好啊。我是Sender"
    
            TimeUnit.MILLISECONDS.sleep(3000)
          }
    
        }
      }
    
      object ActorReciever extends Actor{
        override def act(): Unit = {
          while(true){
            receive{//传入一个偏函数
              case x:String=>println(x)
            }
          }
        }
      }
      
    
      def main(args: Array[String]): Unit = {
        ActorSender.start()
        ActorReciever.start()
      }
    
    }
    View Code

    E:使用loop和react接收优化消息

      使用while(true)会频繁的创建线程,销毁和切换,会影响运行效率

    object Demo05 {
      //创建Sender
      object ActorSender extends Actor{
        override def act(): Unit = {
          while (true){
    
            ActorReciever !"你好啊。我是Sender"
    
            TimeUnit.MILLISECONDS.sleep(3000)
          }
    
        }
      }
    
      object ActorReciever extends Actor{
        override def act(): Unit = {
          loop{
            react{
              case x:String=>println(x)
            }
          }
        }
      }
    
      //创建Receiver
    
      def main(args: Array[String]): Unit = {
        ActorSender.start()
        ActorReciever.start()
      }
    
    }
    View Code

    F:发送和接收自定义消息

    package com.itheima.scala.Actor
    
    import scala.actors.Actor
    
    //案例: Actor发送和接收自定义消息, 采用 同步有返回的形式
    object Demo06 {
    
      //1. 定义两个样例类Message(表示发送数据),   ReplyMessage(表示返回数据.)
      case class Message(id: Int, message: String) //自定义的发送消息 样例类
      case class ReplyMessage(message: String, name: String) //自定义的接收消息 样例类
    
    
      //2. 创建一个MsgActor,用来接收MainActor发送过来的消息, 并向它回复一条消息.
      object MsgActor extends Actor {
        override def act(): Unit = {
          //2.1 接收 主Actor(MainActor) 发送过来的消息.
          loop {
            react {
              //结合偏函数使用
              case Message(id, message) => println(s"我是MsgActor, 我收到的消息是: ${id}, ${message}")
    
              //2.2 给MainActor回复一条消息.
              //sender: 获取消息发送方的Actor对象
              sender ! ReplyMessage("我很不好, 熏死了!...", "车磊")
            }
          }
        }
      }
    
      def main(args: Array[String]): Unit = {
        //3. 开启MsgActor
        MsgActor.start()
    
        //4. 通过MainActor, 给MsgActor发送一个 Message对象.
        //采用 !?  同步有返回.
        val reply:Any = MsgActor !? Message(1, "你好啊, 我是MainActor, 我在给你发消息!")
        //resutl表示最终接收到的 返回消息.
        val result = reply.asInstanceOf[ReplyMessage]
        //5. 输出结果.
        println(result)
      }
    }
    
    package com.itheima.scala.Actor
    
    
    import scala.actors.Actor
    
    //案例: Actor发送和接收自定义消息, 采用 异步 无返回的形式
    object Demo07 {
    
      //1. 定义两个样例类Message(表示发送数据),   ReplyMessage(表示返回数据.)
      case class Message(id: Int, message: String) //自定义的发送消息 样例类
    
      //2. 创建一个MsgActor,用来接收MainActor发送过来的消息, 并向它回复一条消息.
      object MsgActor extends Actor {
        override def act(): Unit = {
          //2.1 接收 主Actor(MainActor) 发送过来的消息.
          loop {
            react {
              //结合偏函数使用
              case Message(id, message) => println(s"我是MsgActor, 我收到的消息是: ${id}, ${message}")
            }
          }
        }
      }
    
      def main(args: Array[String]): Unit = {
        //3. 开启MsgActor
        MsgActor.start()
    
        //4. 通过MainActor, 给MsgActor发送一个 Message对象.
        //采用 !  异步无返回
       MsgActor ! Message(1, "我是采用 异步无返回 的形式发送消息!")
    
      }
    }
    
    
    package com.itheima.scala.Actor
    
    
    import scala.actors.{Actor, Future}
    
    
    //案例: Actor发送和接收自定义消息, 采用 异步有返回的形式
    object Demo08 {
    
      //1. 定义两个样例类Message(表示发送数据),   ReplyMessage(表示返回数据.)
      case class Message(id: Int, message: String) //自定义的发送消息 样例类
      case class ReplyMessage(message: String, name: String) //自定义的接收消息 样例类
    
    
      //2. 创建一个MsgActor,用来接收MainActor发送过来的消息, 并向它回复一条消息.
      object MsgActor extends Actor {
        override def act(): Unit = {
          //2.1 接收 主Actor(MainActor) 发送过来的消息.
          loop {
            react {
              //结合偏函数使用
              case Message(id, message) => println(s"我是MsgActor, 我收到的消息是: ${id}, ${message}")
    
                //2.2 给MainActor回复一条消息.
                //sender: 获取消息发送方的Actor对象
                sender ! ReplyMessage("我很不好, 熏死了!...", "糖糖")
            }
          }
        }
      }
    
      def main(args: Array[String]): Unit = {
        //3. 开启MsgActor
        MsgActor.start()
    
        //4. 通过MainActor, 给MsgActor发送一个 Message对象.
        //采用 !!  异步有返回.
        val future: Future[Any] = MsgActor !! Message(1, "你好啊, 我是MainActor, 我在给你发消息!")
    
        //5. 因为future中不一定会立马有数据, 所以我们要校验.
        //Future的isSet()可检查是否已经收到返回消息,apply()方法可获取返回数据
        //!future.isSet表示: 没有接收到具体的返回消息, 就一直死循环.
        while(!future.isSet){}
    
        //通过Future的apply()方法来获取返回的数据.
        val result = future.apply().asInstanceOf[ReplyMessage]
        //5. 输出结果.
        println(result)
      }
    }
    View Code

     11. WorldCount案例

      需求:在一个文件夹下有多个文件,每个文件中都有若干个单词,单词之间是通过空格隔开。请统计该文件夹下所有的文件中的单词的分别统计个数。

  • 相关阅读:
    使用opencv工程
    面试官最爱问的问题背后真相
    哎,哎,去了清华园
    突然发现兰皙欧洗面奶不错
    crs.exe 进程管理里面的流氓进程之封杀
    初步使用OpenCV
    动态网站基础
    Java IO -- 序列化的疑问
    建造模式
    MYSQL 从头开始-2(join)
  • 原文地址:https://www.cnblogs.com/qidi/p/11773467.html
Copyright © 2020-2023  润新知