函数式编程

  1. 将函数赋值给变量
  2. 匿名函数
  3. 高阶函数
  4. 高级函数的类型推断
  5. scala的常用高阶函数
  6. 闭包
  7. sam转换
  8. currying函数
  9. return

将函数赋值给变量

  1. scala中的函数是一等公民,可以独立定义,独立存在,而且可以直接将函数作为值赋值给变量
scala> def sayHello(name:String){println("Hello, "+name)}
sayHello: (name: String)Unit scala> sayHello("tom")
Hello, tom scala> val sayHelloFunc = sayHello _
sayHelloFunc: String => Unit = $$Lambda$1061/1964697764@235d659c scala> sayHelloFunc("leo")
Hello, leo

匿名函数

  1. scala中,函数也可以不需要命名,此时函数被称为匿名函数
  2. 可以直接定义函数后,将函数赋值给某个变量;也可以将直接定义的匿名函数传入其他函数之中
  3. scala定义匿名函数的语法规则就是,(参数名:参数类型)=>函数体
scala> val sayHelloFunc = (name:String) => println("hello, "+name)
sayHelloFunc: String => Unit = $$Lambda$1070/547507935@29962b2f scala> sayHelloFunc("leo")
hello, leo

高阶函数

  1. scala中函数时一等公民,因此可以直接将某个函数传入其他函数,作为参数。这个功能是及其强大的,也是java这种面向对象的编程语言所不具备的
  2. 接收其他函数作为参数的函数,也被称为高阶函数(higher-order function)
scala> val sayHelloFunc = (name:String)=>println("Hello, "+name)
sayHelloFunc: String => Unit = $$Lambda$1167/1510403823@1c0cf193 scala> def greeting(func:(String)=> Unit,name:String){func(name)}
greeting: (func: String => Unit, name: String)Unit scala> greeting(sayHelloFunc,"leo")
Hello, leo
scala> Array(1,2,3,4,5).map((num:Int)=>num*num)
res5: Array[Int] = Array(1, 4, 9, 16, 25)
  1. 高阶函数的另外一个功能是将函数作为返回值
scala> def getGreetingFunc(msg:String)=(name:String)=>println(msg+","+name)
getGreetingFunc: (msg: String)String => Unit scala> val greetingFunc = getGreetingFunc("hello")
greetingFunc: String => Unit = $$Lambda$1292/1385099824@ae85aad scala> greetingFunc("leo")
hello,leo

高阶函数的类型推断

  1. 高阶函数可以自动判断出参数类型,而不需要写明类型;而且对于只有一个参数的函数,还可以省去其小括号;如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,并且将参数用_来替代
scala> def greeting(func:(String)=>Unit,name:String){func(name)}
greeting: (func: String => Unit, name: String)Unit scala> greeting((name:String)=>println("Hello, "+name),"leo")
Hello, leo scala> greeting((name)=>println("Hello, "+name),"leo")
Hello, leo scala> greeting(name => println("Hello, "+name),"leo")
Hello, leo scala> def triple(func:(Int)=>Int) = {func(3)}
triple: (func: Int => Int)Int scala> triple(3* _)
res10: Int = 9 scala> triple(2+_)
res11: Int = 5

scala的常用高阶函数

scala> Array(1,2,3,4,5).map(2* _)
res13: Array[Int] = Array(2, 4, 6, 8, 10) scala> (1 to 9).map("*"*_).foreach(println _)
*
**
***
****
*****
******
*******
********
********* scala> (1 to 20).filter(_ % 2 == 0)
res16: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20) //从左侧元素开始,进行reduce操作,即先对元素1和元素2进行处理,然后将结果与元素3处理,再将结果与元素4处理,依次类推,即为reduce
// 1*2*3*4*5*6*7*8*9
scala> (1 to 9).reduceLeft(_*_)
res17: Int = 362880 //sortWith:对元素进行两两相比,进行排序
scala> Array(3,2,5,4,10,1).sortWith(_ < _)
res19: Array[Int] = Array(1, 2, 3, 4, 5, 10)

闭包

  1. 闭包最简洁的解释,函数在变量不处于其有效作用域时,还能够对变量进行访问,即为闭包
scala> def getGreetingFunc(msg:String) = (name:String)=>println(msg+","+name)
getGreetingFunc: (msg: String)String => Unit scala> val greetingFuncHello = getGreetingFunc("hello")
greetingFuncHello: String => Unit = $$Lambda$1377/116345573@1f238bc9 scala> val greetingFuncHi = getGreetingFunc("hi")
greetingFuncHi: String => Unit = $$Lambda$1377/116345573@3f33316e scala> greetingFuncHello("leo")
hello,leo scala> greetingFuncHi("leo")
hi,leo
  1. 两次调用getGreetingFunc函数,传入不同的msg,并创建不同的函数返回
  2. 然而,msg只是一个局部变量,却在getGreetingFunc执行完之后,还可以继续存在创建的函数之中,greetingFuncHello("leo")调用时,值为"hello"的msg被保留在了函数体内部,可以反复的使用
  3. 这种变量超出了其作用域,还可以使用的情况,即为闭包
  4. scala通过为每个函数创建对象来实现闭包,实际上对于getGreetingFunc函数创建的函数,msg是作为函数对象的变量存在的,因此每个函数才可以拥有不同的msg
  5. scala编译器会确保上述闭包机制

SAM转换

  1. 在java中,不支持直接将函数传入一个方法作为参数,通常来说,唯一的办法就是定义一个实现了某个接口的类的实例对象,该对象只有一个方法;而这些接口都只有单个的抽象方法,也就是single abstract method,简称SAM
  2. 由于scala是可以调用java的代码的,因此当我们调用java的某个方法时,可能就不得不创建SAM传递给方法,非常麻烦;但是scala又是支持直接传递函数的。此时就可以使用scala提供的,在调用java方法时,使用的功能,SAM转换,即将SAM转换为scala函数
  3. 要使用SAM转换,需要使用scala提供的特性,隐式转换
scala> import javax.swing._
import javax.swing._ scala> import java.awt.event._
import java.awt.event._ scala> val button = new JButton("Click") scala> button.addActionListener(new ActionListener{
| override def actionPerformed(event:ActionEvent){
| println("Click Me!!")
| }
| })
//隐式转换
scala> implicit def getActionListener(actionProcessFunc:(ActionEvent)=>Unit)=new ActionListener{
| override def actionPerformed(event:ActionEvent){
| actionProcessFunc(event)
| }
| } scala> button.addActionListener((event:ActionEvent)=>println("Click Me!!!"))

Currying函数

  1. Curring函数,指的是,将原来接收两个参数的一个函数,转换为两个函数,第一个函数接收原先的第一个参数,然后返回接收原来第二个参数的第二个函数
  2. 在函数调用的过程中,就变为了两个函数去连续调用的形式
scala> def sum(a:Int,b:Int) = a+b
sum: (a: Int, b: Int)Int scala> sum(1,2)
res24: Int = 3 scala> def sum2(a:Int) = (b:Int)=>a+b
sum2: (a: Int)Int => Int scala> sum2(1)(2)
res25: Int = 3 scala> def sum3(a:Int)(b:Int) = a+b
sum3: (a: Int)(b: Int)Int scala> sum3(1)(2)
res26: Int = 3

return

  1. scala中,不需要使用return来返回函数的值,函数最后一行语句的值,就是函数的返回值。在scala中,return用于在匿名函数中返回值给包含匿名函数的带名函数,并作为带名函数的返回值
  2. 使用return的匿名函数,是必须给出返回类型的,否则无法通过编译
scala> :paste
// Entering paste mode (ctrl-D to finish) def greeting(name:String)={
def sayHello(name:String):String={
return "Hello, "+name
}
sayHello(name)
} // Exiting paste mode, now interpreting. greeting: (name: String)String scala> greeting("leo")
res27: String = Hello, leo

Spark基础-scala学习(四、函数式编程)的更多相关文章

  1. Spark基础-scala学习(五、集合)

    集合 scala的集合体系结构 List LinkedList Set 集合的函数式编程 函数式编程综合案例:统计多个文本内的单词总数 scala的集合体系结构 scala中的集合体系主要包括:Ite ...

  2. Scala学习笔记--函数式编程

    一.定义 简单说,"函数式编程"是一种"编程范式"(programming paradigm),也就是如何编写程序的方法论. 它属于"结构化编程&qu ...

  3. Spark基础-scala学习(三、Trait)

    面向对象编程之Trait trait基础知识 将trait作为接口使用 在trait中定义具体方法 在trait中定义具体字段 在trait中定义抽象字段 trait高级知识 为实例对象混入trait ...

  4. Spark基础-scala学习(二、面向对象)

    面向对象编程之类 //定义一个简单的类 scala> :paste // Entering paste mode (ctrl-D to finish) //类默认public的 class He ...

  5. Spark基础-scala学习(一、入门)

    Scala解析器的使用 REPL:Read(取值)-> Evaluation(求值)-> Print(打印)->Loop(循环).scala解析器也被称为REPL,会快速编译scal ...

  6. Spark基础-scala学习(八、隐式转换与隐式参数)

    大纲 隐式转换 使用隐式转换加强现有类型 导入隐式转换函数 隐式转换的发生时机 隐式参数 隐式转换 要实现隐式转换,只要程序可见的范围内定义隐式转换函数即可.Scala会自动使用隐式转换函数.隐式转换 ...

  7. Spark基础-scala学习(七、类型参数)

    类型参数是什么 类似于java泛型,泛型类 泛型函数 上边界Bounds 下边界 View Bounds Context Bounds Manifest Context Bounds 协变和逆变 Ex ...

  8. 大数据技术之_16_Scala学习_04_函数式编程-基础+面向对象编程-基础

    第五章 函数式编程-基础5.1 函数式编程内容说明5.1.1 函数式编程内容5.1.2 函数式编程授课顺序5.2 函数式编程介绍5.2.1 几个概念的说明5.2.2 方法.函数.函数式编程和面向对象编 ...

  9. (数据科学学习手札48)Scala中的函数式编程

    一.简介 Scala作为一门函数式编程与面向对象完美结合的语言,函数式编程部分也有其独到之处,本文就将针对Scala中关于函数式编程的一些常用基本内容进行介绍: 二.在Scala中定义函数 2.1 定 ...

随机推荐

  1. Kafka 性能测试报告

    Producer command: kafka-producer-perf-test --topic _perf-test --num-records 10000000 --record-size 1 ...

  2. java用POI操作excel——随便写一下,最基础的东西

    前两天部门实施在做一个东西,需要把客户放在Excel中的数据导入到Oracle数据库中,我就想着直接写一个模板,必要的时候改一下实体类应该可以解放实施同事的双手,不过在实际写的过程中,还是碰到很多问题 ...

  3. vue项目获取地址栏参数(非路由传参)

    在项目中,遇到一个需求,就是另一个系统直接跳转到我们项目中的某个页面,不需要做用户的校验直接单纯的跳转新页面,再初始化查询数据,参数以地址栏的形式传入 由于原来项目做过权限控制,所以在路由那边需要进行 ...

  4. 人脸检测(1)——HOG特征

    一.概述 前面一个系列,我们对车牌识别的相关技术进行了研究,但是车牌识别相对来说还是比较简单的,后续本人会对人脸检测.人脸识别,人脸姿态估计和人眼识别做一定的学习和研究.其中人脸检测相对来说比较简单, ...

  5. java.sql.SQLException: Field 'id' doesn't have a default value

    1:id 列要设置成自增,自动赋值 java.sql.SQLException: Field 'id' doesn't have a default value at com.mysql.jdbc.S ...

  6. DTO的问题

    首先使用写好的excle将表中的列进行复制,然后生成代码. 实现一个类继承FormCommonDTO.注意父类有的属性子类一定不能写,否则转换时会报错. 字段名字不一样,意义一样的,不能删除

  7. graph_base_pic_segmentation里面的细节和代码

    https://github.com/zhangbo2008/graph_base_pic_segmentation_analyzing/blob/master/README.md

  8. oracle xe在centos下的安装(更)

    更:重新弄了一下,就两个地方要注意,一是hosts文件的主机域名解析,而是profile文件配置,需要从oracle文件里复制过去在profile最下面添加就行了 注:下面方法反正我是失败了,好像xe ...

  9. VMware Workstation:安装windows xp系统

    https://blog.csdn.net/nicergj/article/details/83651603

  10. 在idea中,mavne项目使用mybatis-generator-maven-plugin自动生成实体了的时候,在maven插件里面始终不显示

    最近想学习mybatis的知识,自己搭了个简单的ssm框架,想通过插件自动生成实体类,发现想要的插件一直都没显示出来,着实很郁闷: pom.xm中的配置: <!--mybatis-generat ...