Scala(三)函数式编程、函数式编程之集合操作、模式匹配

  1. 函数式编程:在Scala中函数就是一个完全独立存在的语法,是Java中没有的语法

    1. 将一个函数赋值给一个变量,赋值语法就是在函数名的后边加上空格和下划线

      package com.lyz.scala.two
      
      object Function001 {
        def main(args: Array[String]): Unit = {
      
          //将函数赋值给变量,语法就是函数名和一个下划线
          val sayHello = hello _
      
          sayHello("l4")
        }
      
        //定义一个函数
        def hello(name:String):Unit={
          println("this name is  = " +name)
        }
      }
      
    2. 匿名函数:在Scala中匿名函数是不需要声明函数名的,它可以直接定义函数赋值给一个变量,也可以直接将定义的匿名函数传入其他函数之中。

      package com.lyz.scala.two
      
      object Function002 {
        def main(args: Array[String]): Unit = {
      
          //定义一个匿名函数,不需要函数名,直接赋值给一个变量
          val function0001 = (name:String)=>{
            "this is name = "+name
          }
          //利用变量调用匿名函数
          println(function0001("l4"))
        }
      }
      
    3. 高阶函数:Scala中可以将一个函数作为参数传入另个一函数,这种语法功能是极其强大的。我们把这种接受函数作为参数的函数叫作高阶函数

      package com.lyz.scala.two
      
      object Function003 {
        def main(args: Array[String]): Unit = {
      
          //定义一个匿名函数,返回值为String
          val function003 = (name: String) => {
            "this is name = " + name
          }
          println(function0003(function003, name = "l4"))
        }
      
        /** *
          * 高阶函数,返回值为String
          *
          * @param function :它是一个函数,其语法解释为: 自定义方法名:(传入的数据类型为String) => 返回值类型为String
          * @param name     就是具体的参数表了
          */
        def function0003(function: (String) => String, name: String): String = {
          function(name)
        }
      }
      
    4. 高阶函数返回一个函数

      package com.lyz.scala.two
      
      object Function004 {
        def main(args: Array[String]): Unit = {
      
          val function00005 = function0004("l4")
          println(function00005("z3",10))
        }
      
        /**
          * 高阶函数,以一个函数作为返回值
          * 以下是从高阶函数开始的对这个高阶函数的拆分解释:
          *
          * 1.(msg: String):高阶函数传入的参数类型
          * 2.(String,Int):高阶函数返回的函数的参数类型,要与后边的返回函数参数类型一一对应
          * 3.String:返回函数的返回值类型
          * 4.(name: String,age:Int):高阶函数返回的函数的参数类型
          */
      
        def function0004(msg: String): (String,Int) => String = (name: String,age:Int) => {
          msg + " : " + name+age
        }
      }
      
    5. Scala中常用的高阶函数:

      package com.lyz.scala.two
      
      object Function005 {
        def main(args: Array[String]): Unit = {
          //Scala里常用的高阶函数
          val array = Array(1 to 10: _*)
          //map
          for (elem <- array.map(_ * 3)) {
            println(elem)
          }
      
          //foreach 没有返回值
          array.map(_ * 3).foreach(println(_))
      
          //filter 用于过滤数据
          array.map(_ * 3).filter(_ == 30).foreach(println(_))
      
          //reduceLeft:从左到右依次执行乘法,如 1*2得到的结果在于3相乘,依次类推,现在这个函数已经被 product所代替了。下边两个是等价的
          println(array.reduceLeft(_ * _))
          println(array.product)
      
          //sortWith:两个两个相比较,类似于冒泡排序
          for (elem <- array.reverse.sortWith(_ < _)) {
            print(elem)
          }
        }
      }
      
    6. 闭包:在Scala中,函数访问其作用域之外的变量称为闭包。其原理为Scala为每个函数创建对象来实现闭包,实际上作用域之外的变量就会称为函数对象里的变量,这样每个函数就会有这不同的变量,Scala编译器确保闭包机制

      package com.lyz.scala.two
      
      object Function006 {
        def main(args: Array[String]): Unit = {
      
          //返回的函数体是能够访问 "hello" 这个实际变量的,这就是闭包
          val hi = hello("hello")
      
          //打印结果为 hello,l4
          hi("l4")
        }
      
        /**
          * 1.以下是一个高阶函数,也是一个闭包语法
          * 2.msg变量相对于要返回的匿名函数来说是一个外部变量
          * 3.被返回的函数里能够一直保存外部变量,随着函数返回
          * 4.这种机制就叫做闭包
          * 5.闭包的原理就是Scala为每个函数都创建一个对象,然后将外部变量作为对象的变量的存在,而且还可以使用的情况叫闭包
          */
      
        def hello(msg: String): String => Unit = (name: String) => {
          println(msg, name)
        }
      }
      
    7. SAM(Single Abastract Method):

    8. currying函数:将原来接受两个参数的一个函数转换成两个函数,第一个函数接受第一个参数,然后返回接受第二个参数的函数,在函数调用中就成了两个函数连续调用的形式,

      package com.lyz.scala.two
      
      object Function007 {
        def main(args: Array[String]): Unit = {
      
          def hello(name: String) = (age: Int) => println(age, name)
          hello("l4")(10)
      
          def hello1(name: String)(age: Int): Unit = println(name, age)
          hello1("l4")(10)
        }
      }
  2. 集合操作:Scala中的集合体系主要包括IterableSeqSetMap。其中Iterable是所有集合的Trait的跟Trait,类似于Java里的Collection。Scala集合分为可变不可变的,可变的在mutable包里,不可变的在immutable包里。Seq下包含Range、ArrayBuffer、List、等子Trart。其中Range就代表一个序列,通常用 1 to 10 来产生一个Range序列、ArrayBuffer就相当于ArrayList。

    1. List:代表一个不可变的列表,他又head和tail方法,head是List第一个元素,tail是除第一个元素的所有元素。List有特殊操作符双冒号(::)0::list 0代表head,list代表tail,这个语法就是合成一个新的List。

      package com.lyz.scala.three
      
      object ListLearn {
        def main(args: Array[String]): Unit = {
      
          val list = List(1,2,3,4)
      
          list.head //list的第一个元素
          list.tail //除了第一个元素的所有元素
      
          val  newlist = 0::list
      
          /**
            * 打印结果:0,1,2,3,4
            */
          for (elem <- newlist) {
            println(elem)
          }
        }
      }
      
    2. Set:无序并且元素不会重复的集合

      package com.lyz.scala.three
      
      import scala.collection.mutable
      
      object SetLearn {
        def main(args: Array[String]): Unit = {
      
          //无序
          val set = new mutable.HashSet[String]()
          set.add("aaaaaa")
          set.add("aaaaaa")
          for (elem <- set) {
            println(elem)
          }
      
          //按照添加元素的顺序存放元素
          val linkset = new mutable.LinkedHashSet[String]()
          linkset.add("aaaa")
          linkset.add("aaaa")
          linkset.add("bbbb")
          for (elem <- linkset) {println(elem)}
      
        }
      }
      
  3. 模式匹配:在Scala中模式匹配是很有特色的,功能很强大。类似于Java中的switch case语法,但是Scala中的模式匹配要比Java功能强大的多,因为Scala中的模式匹配不仅能对值进行匹配,还可以对类型进行匹配,对Array和List的元素情况进行匹配,还可以对case class进行匹配,甚至对有值或者没值进行匹配。

    1. 基本语法

      package com.lyz.scala.three
      
      object MatchLearn {
        def main(args: Array[String]): Unit = {
          hello("cccc",11)
        }
      
        def hello(name: String,age:Int): Unit = {
      
          //与Java不同,不需要break跳出。scala中只要匹配就不在继续向下执行
          name match {
            case "A" => println("A")
            case "B" => println("B")
            case "C" => println("C")
            case "D" => println("D")
            // if守卫 语法就是 case+空格+下划线+逻辑
            case otherField if name.contains("aaa")=>println("name包含了aaa:"+otherField) //对值得进一步细化,并将匹配到的值赋值给 otherField,注意这里的值针对的是 name
      
            //上述匹配都不匹配,但是if守卫匹配了,也可以匹配出结果
            case otherField if age==10 =>println("匹配到了10:"+otherField) //将匹配到的值赋值给 otherField,注意这里的值针对的是 name
            case _ => println("上述情况都不匹配")
          }
        }
      }
      
    2. 对类型进行模式匹配:直接匹配变量的类型

      package com.lyz.scala.three
      
      object MatchLearn {
        def main(args: Array[String]): Unit = {
          classCase(new B())//我是B类型com.lyz.scala.three.B@1134affc
          classCase(new C())//我是C类型com.lyz.scala.three.C@d041cf
          classCase(null)//我既不是A类型也不是B类型
        }
        def classCase(a: A): Unit = {
          a match {
            case b: B => println("我是B类型" + b)
            case c: C => println("我是C类型" + c)
            case _ => println("我既不是A类型也不是B类型")
          }
        }
      }
      
      class A
      class B extends A
      class C extends A
    3. 对Array和List进行模式匹配

      package com.lyz.scala.three
      
      object ArrayMatch {
        def main(args: Array[String]): Unit = {
          hello(Array()) //一个人都没有呀
          hello(Array("l4")) //我 是 l4
          hello(Array("l4", "w5")) //来了这么多人呀
          hello(Array("l4", "w5", "z6")) //(l4,w5,z6)
        }
      
        def hello(array: Array[String]): Unit = {
          array match {
            case Array("l4") => println("我 是 l4")
            case Array(one, two, three) => println(one, two, three)
            case Array("l4", _*) => println("来了这么多人呀")
            case _ => println("一个人都没有呀")
          }
        }
      }
      
    4. 对case class进行模式匹配:Scala中提供了一种特殊的类,以case修饰的类,这种类是没有方法的,只有属性字段,字段不需要提供var或者val,因为scala默认提供的实val,并且scala自动会给这种类提供getter和setter方法以及半生对象,并且半生对象提供了apply方法。

      package com.lyz.scala.three
      
      object CaseClassMath {
        def main(args: Array[String]): Unit = {
          hello(Student("l4",10))//我是 student
          hello(Teach("w5"))//我是 teach
        }
      
        def hello(person: Person): Unit = {
          person match {
            case Student(name: String, age: Int) => println("我是 student")
            case Teach(name: String) => println("我是 teach")
            case _ =>println("我啥也不是")
          }
        }
      }
      
      class Person()
      case class Student(name: String, age: Int) extends Person
      case class Teach(name: String) extends Person
    5. Option与模式匹配:Option只有两种情况,有值为Some,无值为None。Option用于模式匹配来验证某个变量是否有值

      package com.lyz.scala.three
      
      import scala.collection.mutable
      
      object OptionMatch {
      
        def main(args: Array[String]): Unit = {
          val map = new mutable.HashMap[String, Int]()
          map.put("1", 1)
          map.put("2", 2)
          map.put("3", 3)
      
          hello("1", map) //map里不存在这个值
          hello("4", map) //map里不存在这个值
        }
      
        def hello(key: String, map: mutable.HashMap[String, Int]): Unit = {
          val value = map.get("key")
      
          value match {
            case Some(value) => println("map里存在这个值")
            case None => println("map里不存在这个值")
          }
        }
      }
      

猜你喜欢

转载自blog.csdn.net/suubyy/article/details/80661164