日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

大數(shù)據(jù)學(xué)習(xí)路線分享高階函數(shù)

 好程序員IT 2019-08-21

  大數(shù)據(jù)學(xué)習(xí)路線分享高階函數(shù)我們通常將可以做為參數(shù)傳遞到方法中的表達(dá)式叫做函數(shù)

  高階函數(shù)包含:作為值的函數(shù)、匿名函數(shù)、閉包、柯里化等等。

  定義函數(shù)時(shí)格式:val 變量名 = (輸入?yún)?shù)類型和個(gè)數(shù)) => 函數(shù)實(shí)現(xiàn)和返回值類型和個(gè)數(shù)

  “=”表示將函數(shù)賦給一個(gè)變量

  “=>”左面表示輸入?yún)?shù)名稱、類型和個(gè)數(shù),右邊表示函數(shù)的實(shí)現(xiàn)和返回值類型和參數(shù)個(gè)數(shù)

  作為值的函數(shù)

定義函數(shù)

scala> val func = (x:Int) => x * x

func: Int => Int = <function1>

scala> val func:Int => Int = x => x * x

func: Int => Int = <function1>

scala> func(3)

res0: Int = 9

函數(shù)調(diào)用

scala> val arr = Array(1,2,3,4)

arr: Array[Int] = Array(1, 2, 3, 4)

scala> val res = arr.map(x => func(x))

res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(func(_))

res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(func)

res: Array[Int] = Array(1, 4, 9, 16)

將方法轉(zhuǎn)化為函數(shù)

scala> def m1(x:Int):Int = x * x

m1: (x: Int)Int

scala> def m1(x:Int) = x * x

m1: (x: Int)Int

scala> def m2(x:Int) {x * x}

m2: (x: Int)Unit

scala> val f1 = m1 _

f1: Int => Int = <function1>

scala> val res = arr.map(x => m1(x))

res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(m1(_))

res: Array[Int] = Array(1, 4, 9, 16)

scala> val res = arr.map(m1)

res: Array[Int] = Array(1, 4, 9, 16)

匿名函數(shù)

Scala中,你不需要給每一個(gè)函數(shù)命名,沒有將函數(shù)賦給變量的函數(shù)叫做匿名函數(shù)

scala> arr.map((x:Int) => x * x)

res3: Array[Int] = Array(1, 4, 9, 16)

scala> arr.map(x => x * x)

res4: Array[Int] = Array(1, 4, 9, 16)

scala> arr.map(m1)

res1: Array[Int] = Array(1, 4, 9, 16)

scala> arr.map(_ * 2)

res2: Array[Int] = Array(2, 4, 6, 8)

閉包

閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)

可以理解成,定義在一個(gè)函數(shù)內(nèi)部的函數(shù)

本質(zhì)上,閉包是將函數(shù)內(nèi)部和函數(shù)外部鏈接起來的橋梁

object Bibao {

  def sum(f:Int => Int):(Int,Int) => Int = {

    def sumf(a:Int,b:Int):Int = {

      if (a > b) 0 else f(a)+sumf(a + 1,b)

    }

    sumf  //隱式轉(zhuǎn)換成函數(shù)

  }

  def main(args: Array[String]): Unit = {

    def sumInts = sum(x => x)

    println(sumInts(1,2))

  }

}

柯里化

柯里化指的是將原來接收兩個(gè)參數(shù)列表的方法或函數(shù)變成新的一個(gè)參數(shù)列表的方法或函數(shù)的過程

聲明和轉(zhuǎn)化

scala> def curry(x:Int)(y:Int) = x * y  //聲明

curry: (x: Int)(y: Int)Int

scala> curry(3)(4)

res8: Int = 12

scala> val curry1 = curry(3) _  //轉(zhuǎn)換成方法 : "_"

curry1: Int => Int = <function1>

scala> curry1(5)

res9: Int = 15

scala> def curry2(x:Int) = (y:Int) => x * y  //聲明

curry2: (x: Int)Int => Int

scala> val func = curry2(2)  //直接轉(zhuǎn)化

func: Int => Int = <function1>

scala> func(4)

res16: Int = 8

scala> def curry3() = (x:Int) => x * x

curry3: ()Int => Int

scala> val func = curry3()    //轉(zhuǎn)化空參

func: Int => Int = <function1>

scala> func(3)

res17: Int = 9

柯里化需要與隱式轉(zhuǎn)換相結(jié)合

implicit  隱式的 -> 隱式值在當(dāng)前會(huì)話中同類型只能定義一次,不同類型可定義多個(gè)

scala> def m1(x:Int)(implicit y:Int=5) = x * y

m1: (x: Int)(implicit y: Int)Int

scala> m1(3)

res10: Int = 15

scala> m1(3)(6)    //隱式值可以改變

res11: Int = 18

scala> implicit val x = 100  //定義成全局的隱式值,可以覆蓋

x: Int = 100

scala> m1(3)(6)

res12: Int = 18

scala> m1(3)

res13: Int = 300

scala> implicit val y = "abc"

y: String = abc

案例: 把數(shù)組中元祖的value相加

scala> val arr = Array(("xixi",1),("haha",2),("heihei",3))

arr: Array[(String, Int)] = Array((xixi,1), (haha,2), (heihei,3))

scala>  arr.foldLeft(0)(_ + _._2)  //(初始值)(上次計(jì)算結(jié)果+循環(huán)出的結(jié)果)

res15: Int = 6

CurryDemo

object Context{   //一般情況會(huì)新建類,再在此地調(diào)用

  implicit val a = "yaoyao"

  implicit val b = 100

}

object Curry {

  //與變量沒有關(guān)系,系統(tǒng)自己匹配相同類型的值

  implicit val a = "yaoyao"

  implicit val b = 100

  def m1(str:String)(implicit name:String="xiaodan"){

    println(str + name)

  }

  def main(args: Array[String]): Unit = {

    import Context.a

    m1("Hello ")

  }

}

隱式轉(zhuǎn)換

作用: 隱式的對(duì)類的方法進(jìn)行增強(qiáng),豐富現(xiàn)有類庫的功能

隱式轉(zhuǎn)換:

繼承 -> 通過方法的重寫來對(duì)父類的方法增強(qiáng)

代理模式 -> 遠(yuǎn)程代理,多用于網(wǎng)站,代理一個(gè)實(shí)例,可以對(duì)實(shí)例方法增強(qiáng),在調(diào)用方法之前

        代理,方法之后環(huán)繞

    裝飾模式 -> 裝飾模式也叫包裝模式,java讀取文件時(shí)要用到IO,也是對(duì)實(shí)例方法增強(qiáng)                          

    new BufferInputStream(new FileInputStream).read()

就是用到了裝飾模式和門面模式 ->

裝飾模式是顯示的包裝,隱式轉(zhuǎn)換就是隱式的做了包裝

門面模式起到了隱式包裝的作用

隱式轉(zhuǎn)換函數(shù) : 是指以implicit關(guān)鍵字聲明的帶有單個(gè)參數(shù)的函數(shù)

案例: 用隱式轉(zhuǎn)換,實(shí)現(xiàn)從給定的URI直接能調(diào)用read方法讀取文件內(nèi)容

object MyPredef {

  //implicit def fileToRichFile(file:String) = new RichFile(file)

  implicit val fileToRichFile = (file:String) =>new RichFile(file)

}

object RichFile {

  def main(args: Array[String]): Unit = {

    val file = "e://wordcount.txt"

//    //顯示的實(shí)現(xiàn)了對(duì)file的方法增強(qiáng)

//    val richFile = new RichFile(file)

//    val content: String = richFile.read()

//    println(content)

    //隱式轉(zhuǎn)換

    import MyPredef.fileToRichFile

    val content = file.read()

    println(content)

  }

}

class RichFile(val file:String){

  //創(chuàng)建read方法

  def read():String = {

    Source.fromFile(file).mkString

  }

}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多