Scala 方法是类的一部分,而函数是一个对象可以赋值给一个变量。换句话来说在类中定义的函数即是方法。
Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
Scala 中使用 val 语句可以定义函数,def 语句定义方法
如果你不写等于号和方法主体,那么方法会被隐式声明为抽象(abstract),包含它的类型于是也是一个抽象类型
def functionName ([参数列表]):[return type]示例
//有返回值 def add(a:Int,b:Int):Int={ var sum:Int=0 sum=a+b return sum } //无返回值 def printMe( ) : Unit = { println("Hello, Scala!") }函数式接口
一种只含有一个抽象方法声明的接口可以使用匿名内部类类实例化函数式接口的对象通过lambda表达式可以进一步简化代码lambda语法
(parameters)->expression (parameters)_>{statements;...}内置四大函数式接口
消费接口:Consumer供给型接口:Supplier断言型接口:Predicate函数型接口:Function<T,R>示例
Consumer<String> consumer=(s)-> System.out.println(s.toUpperCase()); consumer.accept("testabc"); list.foreach(x-> System.out.println(x);) Supplier <Double> supplier = () -> Math.random(); System.out.println(supplier.get()); Predicate<String> condition=s -> s.length()>4; if(condition.test("hello")) System.out.println("true"); Function<String,String> toUpper=(s)->s.toUpperCase(); System.out.println(toUpper.apply("test"));传值调用时,参数只在调用时计算一次,后续重复使用计算的结果
def square(x: Int): Int = { println(x) //3 x * x //计算3*3 } square(1+2) //先计算1+2传名调用时,参数在调用时不会计算,只有真正用到参数时才计算
def square(x: => Int): Int = { println(x) //计算1+2 x * x //计算(1+2)*(1+2) } square(1+2) //调用时不计算(参数列表)=>{函数体}
指不含函数名称的函数匿名函数定义 “=>”左边为参数列表 “=>”右边为函数体 如果函数体包括多条语句,应使用“{}”包含 val f1=(x:Int)=>{println(x);x*x}//将匿名函数赋值给变量f1 println(f1(2)) //输出 2 4使用高阶函数实现wordcount
//定义一个list scala> val list6=List("hadoop spark","hello world","hello java") list6: List[String] = List(hadoop spark, hello world, hello java) //1.将list6进行空格切割 scala> list6.map(_.split(" ")) res25: List[Array[String]] = List(Array(hadoop, spark), Array(hello, world), Array(hello, java)) //2.切割后进行平摊 scala> list6.map(_.split(" ")).flatten res27: List[String] = List(hadoop, spark, hello, world, hello, java) //上面两步的合并操作 scala> list6.flatMap(_.split(" ")) res28: List[String] = List(hadoop, spark, hello, world, hello, java) //3.将没个单词转成元组,方便后面进统计(hadoop,1) scala> list6.flatMap(_.split(" ")).map(x=>(x,1)) res29: List[(String, Int)] = List((hadoop,1), (spark,1), (hello,1), (world,1), (hello,1), (java,1)) //4.通过对单词进行分组,即根据元组的第一个元素进行分组 scala> list6.flatMap(_.split(" ")).map(x=>(x,1)).groupBy(x=>x._1) res30: scala.collection.immutable.Map[String,List[(String, Int)]] = Map(world -> List((world,1)), java -> List((java,1)), hadoop -> List((hadoop,1)), spark -> List((spark,1)), hello -> List((hello,1), (hello,1))) //5.通过对组内元素进行统计得出数量 scala> list6.flatMap(_.split(" ")).map(x=>(x,1)).groupBy(x=>x._1).map(x=>(x._1,x._2.size)) res32: scala.collection.immutable.Map[String,Int] = Map(world -> 1, java -> 1, hadoop -> 1, spark -> 1, hello -> 2) //6.遍历打印出来 scala> list6.flatMap(_.split(" ")).map(x=>(x,1)).groupBy(x=>x._1).map(x=>(x._1,x._2.size)).foreach(println) (world,1) (java,1) (hadoop,1) (spark,1) (hello,2) //7.进行简化打印出来 scala> list6.flatMap(_.split(" ")).map((_,1)).groupBy(_._1).map(x=>(x._1,x._2.size)).foreach(println) (world,1) (java,1) (hadoop,1) (spark,1) (hello,2) //扩展:进行安装次数排序 scala> list7.map(_.split(" ")).flatten.map(x=>(x,1)).groupBy(x=>x._1).map(x=>(x._1,x._2.size)).toList res62: List[(String, Int)] = List((are,1), (am,3), (oldhu,1), (i,3), (you,1), (who,1), (ok,1), (fine,1)) //将元组的元素进行调换 scala> list7.map(_.split(" ")).flatten.map(x=>(x,1)).groupBy(x=>x._1).map(x=>(x._1,x._2.size)).toList.map(x=>(x._2,x._1) ) res65: List[(Int, String)] = List((1,are), (3,am), (1,oldhu), (3,i), (1,you), (1,who), (1,ok), (1,fine)) //降序排序 scala> list7.map(_.split(" ")).flatten.map(x=>(x,1)).groupBy(x=>x._1).map(x=>(x._1,x._2.size)).toList.map(x=>(x._2,x._1)).sortBy(x=>x._1*(-1)) res66: List[(Int, String)] = List((3,am), (3,i), (1,are), (1,oldhu), (1,you), (1,who), (1,ok), (1,fine)) //打印出来 scala> list7.map(_.split(" ")).flatten.map(x=>(x,1)).groupBy(x=>x._1).map(x=>(x._1,x._2.size)).toList.map(x=>(x._2,x._1)).sortBy(x=>x._1*(-1)).foreach(println) (3,am) (3,i) (1,are) (1,oldhu) (1,you) (1,who) (1,ok) (1,fine)Scala函数内可以定义函数,函数内的函数也称局部函数或者内嵌函数
//进行阶乘计算 //调用函数 println(factorial(4)) //定义一个外层函数 def factorial(i:Int):Int={ //定义一个嵌套函数 def fact(i:Int,acc:Int):Int={ if(i<=1){ acc }else{ fact(i-1,i*acc) } } fact(i,acc=1) } //输出 24fold(0)()就是柯里化使用
//单参数列表 def modN(n: Int,x: Int) = ((x % n) == 0) //多参数列表 def modN(n: Int)(x: Int) = ((x % n) == 0) //新函数接收剩余的参数列表作为其参数 def f1(x: Int) = modN(10)(x) def f2(n: Int) = modN(n)(10) def f3 = modN(10)(_)类型转换
implicit def double2Int(x:Double)=x.toInt val i:Int=3.5类型增强
implicit def bool2Int(x:Boolean)=if(x) 1 else 0 println(1+true) //输出 2需求说明 定义一个没有返回值的函数,实现输入一个整数,打印金字塔。例如输入5,打印如下:
object test02 { def main(args: Array[String]): Unit = { print1(5) } def print1(x:Int)={ for(i <-1 to x){//行数 for (j<- 0 to x-i){ print(" ") } for(j <-1 to 2*i-1){ print("*") } println() } } }需求说明 定义一个去除字符串首尾空格的函数字面量trim 定义一个截取字符串首字母的函数字面量initial
def main(args: Array[String]): Unit = { println(f1(" dfsdf ")) println(f2("tdasdfsad")) } val f1=(x:String)=>x.trim; val f2=(y:String)=>y.substring(0,1)//包括索引0,不包括1编写函数values(fun:(Int)=>Int,low:Int,hight:Int) 该函数输出一个集合,对应给定区间内给定函数的输入和输出,比如values(x=>x*x,-5,5)将输出:
(-5,25) (-4,16) (-3,9) (-2,4) (-1,1) (0,0) (1,1) (2,4) (3,9) (4,16) (5,25)使用map()函数实现上述逻辑
import scala.collection.mutable.ListBuffer object test02 { def main(args: Array[String]): Unit = { println(values(x=>x*x, -5, 5)) } def fun(x:Int,y:Int)=x*x def values(fun:Int=>Int,low:Int,hight:Int): ListBuffer[(Int,Int)]={ var list=new ListBuffer[(Int,Int)] for (i <-low to hight) list.append((i,fun(i))) list } } //输出 ListBuffer((-5,25), (-4,16), (-3,9), (-2,4), (-1,1), (0,0), (1,1), (2,4), (3,9), (4,16), (5,25))需求说明 编写Scala函数实现斐波纳契数列
输出 1、1、2、3、5、8、13、21、……
object test02 extends App { //使用递归函数 def fun(x:Int)= { def feibo(x:Int):Int=if (x==1||x==2) 1 else feibo(x-1)+feibo(x-2) (1 to x).toArray.map(x=>feibo(x)) } fun(10).foreach(x=>print(x+" ")) }