Scala函数式编程

函数的定义和使用

函数类型

  • 函数的输入参数的类型以及返回值的类型一起构成函数类型,(Int)=>Int
  • 当参数只有一个时,圆括号可以省略;只有存在多个参数是,圆括号才是必须的。Int=>Int

函数值

  • (value)=>{value+=1}//只有一条语句时,大括号可以省略,(value)=>value+=1.

定义函数

  • val counter:Int=>Int = {(value)=>value+=1}
  • (value)=>value+=1也叫函数字面量

匿名函数

  • 匿名函数也叫lambda表达式
  • (参数)=>表达式,如果不能通过表达式推断出类型,参数中要给出类型;如果参数只有一个,圆括号可省。如(num:Int)=>num*2

函数的使用

val myNumFunc:Int=>Int=(num:Int)=>num*2
println(myNumFunc(3))
val myNumFunc=(num:Int)=>num*2//自动推断类型
println(myNumFunc(3))
val myNumFunc=(num)=>num*2//报错
val myNumFunc:Int=>Int=(num)=>num*2
  • 当函数参数在函数字面量中只出现一次时,可以用_代替
val counter=(_:Int)+1//有类型时括号不能省略,等效于x:Int=>x+1
val add=(_:Int)+(_:Int)//等效于(a:Int,b:Int)=>a+b
val m1=List(1,2,3)
val m2=m1.map(_*2)//map接受一个函数作为参数,相当于m1.map(x=>x*2)

高阶函数

  • 函数的参数又是一个函数,称为高阶函数
//求2的幂次
def powerOfTwo(x:Int):Int={if(x==0) 1 else 2*powerOfTwo(x-1)}
//连加和
def sumInts(a:Int,b:Int):Int={
    if(a>b) 0 else a+sumInts(a+1,b)
}
//平方和
def numSquares(a:Int,b:Int):Int={
    if(a>b) 0 else a*a+numSquares(a+1,b)
}
//幂次和
def sumPowersOfTwo(a:Int,b:Int):Int={
    if(a>b) 0 else powerOfTwo(a)+sumPowersOfTwo(a+1,b)
}
def sum(f:Int=>Int,a:Int,b:Int):Int={
    if(a>b) 0 else f(a)+sum(f,a+1,b)
}
sum(x=>x,1,5)//求连加和,直接传入一个匿名函数
//且省略了参数x的类型,因为可以由sum的参数类型推断出来
sum(x=>x*x,1,5)//求平方和
sum(powerOfTwo,1,5)//幂次和

针对容器的操作

遍历

val list=List(1,2,3)
val f=(i:Int)=>println(i)
list.foreach(f)//遍历集合
val university=Map("XMU"->"Xiamen University","THU"->"Tsinghua University","PKU"->"Peking University")
university foreach {kv=>println(kv._1+":"+kv._2)}//遍历映射,kv是元组对象
university foreach {x=>x match {case (k,v)=>println(k+":"+v)}}//通过元组对象的unapply方法遍历,(k,v),元组对象定义时不需要加类名
university foreach {case (k,v)=>println(k+":"+v)}//不需要加match

映射

  • map:一对一映射
  • flatMap:一对多
val books=List("Hadoop","Hive","HDFS")
books.map(s=>s.toUpperCase)//toUpperCase方法将一个字符串中的每个字母都变成大写
books.map(s=>s.length)//将字符串映射到它的长度
books flatMap (s=>s.toList)//每个元素转成一个列表,在合并成一个总列表,List[Char]=List(H,a,d,o,o,p,H,i,v,e,H,D,F,S)

过滤

val university=Map("XMU"->"Xiamen University","THU"->"Tsinghua University","PKU"->"Peking University")
val xmus=university filter {kv=>kv._2 contains "Xiamen"}//Map(XMU->Xiamen University)
val l=List(1,2,3,4,5,6) filter {_%2==0}//使用了占位符语法,过滤能被2整除的元素,List(2,4,6)

归约

  • 接收有2个参数的函数
  • 分为左归约和右归约
  • reduce方法没有初值,fold方法有初值
val list=List(1,2,3,4,5)
list.reduce(_+_)//将列表元素累加,使用了占位符语法
list.reduce(_*_)//将列表元素连乘
list map (_.toString) reduce ((x,y)=>s"f($x,$y)")//f表示传入reduce的二元函数
val list=List(1,2,3,4,5)
list reduceLeft {_-_}//-13
list reduceRight {_-_}//1-(2-(3-(4-5)))=3
list.fold(10)(_*_)//1200
(list fold 10)(_*_)//fold的中缀调用写法
(list foldLeft 10)(_-_)//计算顺序(((((10-1)-2)-3)-4)-5)=-5
(list foldRight 10)(_-_)//计算顺序(1-(2-(3-(4-(5-10)))))=-7

函数式编程实例WordCount

import java.io.File
import scala.io.Source
import collection.mutable.Map
object WordCount{
    def main(args:Array[String]){
        val dirfile=new File("testfiles")
        val files=dirfile.listFiles//列出目录下所有文件
        val results=Map.empty[String,Int]//声明一个空Map
        for(file<-files){
            val data=Source.fromFile(file)
            val strs=data.getLines.flatMap{s=>s.split(" ")}//getLines得到String字符串类型
            strs foreach {word=>if(results.contains(word)) results(word)+=1 else results(word)=1}
            
        }
        results foreach {case (k,v)=>println(s"$k:$v")}
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值