scala高阶函数和List、Set集合
scala高阶函数和List、Set集合
给函数起名
格式:
val 函数别名 = fun _
object Test1 {
def main(args: Array[String]): Unit = {
val n = fun _ //给函数起名
val result = n(6)
println(result)
}
def fun(a:Int):Int={
a*2
}
}
匿名函数
格式:
(参数名1:数据类型,参数名2:数据类型…)=>{函数体}
val f = (a:Double,b:Double)=>a+b
val result1 = f(3,4)
println(result1)
高阶函数
定义:带函数参数的函数就是高阶函数
例:
def fun2(name:String,f:(String)=>Unit):Unit={
f(name)
}
调用此函数:
方式一:
fun2("zhangsan",(a:String)=>println(a))
方式二:
方式一中使用匿名函数来作为高阶函数的参数,由于定义的变量在=>后面只出现了一次,所以a可以用_代替,同时可以省略=>前面的参数
fun2("lisi",println(_))
方式三:
方式一和方式二都使用的是匿名函数作为高阶函数的参数,这里也可以使用普通函数作为高阶函数的参数
//首先定义一个函数只有一个参数,类型为String,无返回值
def fun3(name:String): Unit ={
println(name)
}
//在main方法中调用高阶函数
fun2("lisi",fun3 _)
高阶函数的案例
-
遍历数组或集合
val arr = Array(3, 5, 7, 9, 0) //遍历数组或集合 arr.foreach((x: Int) => print(x + "\t")) arr.foreach(println(_))
-
map函数,完成数据清洗
//val arr1 = arr.map(_*2) val arr1 = arr.map((x:Int) => x * 2) arr1.foreach(println(_))
-
实现如下效果
/* 实现如下效果: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 思路:2*“*”=“**”,1 to 9数组进行数据清洗得到以上字符串数组,然后遍历输出 */ (1 to 9).map((x:Int)=>"*"*x).forearch(println(_)) (1 to 9).map("*" * _).foreach(println(_))
-
按照过滤条件,将原集合中不符合条件的数据过滤掉
获取1 to 9中的偶数(1 to 9).filter((x: Int) => x % 2 == 0).foreach(println(_)) (1 to 9).filter(_ % 2 == 0).foreach(println(_))
-
求1~9的和
val sum = (1 to 9).reduce((x: Int, y: Int) => x + y) val sum2 = (1 to 9).reduce(_ + _)
运算方式:
x y x+y 1 2 3 3 3 6 6 4 10 10 5 15 15 6 21 21 7 28 28 8 36 36 9 45 reduceRight
从右往左运算val sum3 = (1 to 9).reduceRight(_ - _)//5
x y x-y 8 9 -1 7 -1 8 6 8 -2 5 -2 7 4 7 -3 3 -3 6 2 6 -4 1 -4 5 -
//数组排序
(1 to 9).sortWith((x:Int,y:Int)=>x>y).foreach(println(_))
(1 to 9).sortWith(_ > _).foreach(println(_))
高阶函数练习
-
编写函数values(fun:(Int)=>Int,low:Int,high:Int),该函数输出一个集合,对应给定区间内给定函数的输入和输出。比如,values(x=>x*x,-5,5)应该产出一个对偶的集合(-5,25),(-4,16),(-3,9),···,(5,25)
def values(fun:(Int)=>Int,low:Int,high:Int): ArrayBuffer[Tuple2[Int,Int]] ={//ArrayBuffer中的类型为元组类型,元组中有两个数,都是Int类型 val arrayBuffer = new ArrayBuffer[Tuple2[Int,Int]]() (low to high).foreach((x:Int)=>{ val t = (x,fun(x)) arrayBuffer.append(t) }) arrayBuffer } //调用此函数 val arrayBuffer = values(x=>x*x,-5,5) println(arrayBuffer)
-
如何用reduceleft得到数组中的最大元素
def getMax(): Int ={ (1 to 9).reduceLeft(Math.max(_,_)) } def getMax1(): Int ={ (1 to 9).reduceLeft((x:Int,y:Int)=>if(x > y)x else y) } //调用此函数 val max = getMax() println(max) val max1 = getMax1() println(max1)
-
用to和reduceLeft实现阶乘函数,不得使用循环或递归
def JieChen(n:Int): Int ={ (1 to n).reduceLeft(_*_) } //调用此函数 val jieChen = JieChen(9) println(jieChen)
-
前一个实现需要处理一个特殊情况,即n<1的情况。展示如何用foldLeft来避免这个需要。(在Scaladoc中查找foldLeft的说明。它和reduceLeft很像,只不过所有需要结合在一起的这些值的首值在调用的时候给出。)
def JieChen1(n:Int): Int ={ (1 to n).foldLeft(1)(_*_)//初始值为1 } //调用此函数 val jieChen1 = JieChen1(9) println(jieChen1)
-
编写函数largest(fun:(Int)=>Int,inputs:Seq[Int]),输出在给定输入序列中给定函数的最大值。举例来说,largest(x=>10x-xx,1 to 10)应该返回25。不得使用循环或递归
def largest(fun:(Int)=>Int,inputs:Seq[Int]): Int ={ inputs.map(fun(_)).reduceLeft((x:Int,y:Int)=>if( x > y ) x else y) } //调用此函数 val largests = largest((x:Int)=>10*x-x*x,1 to 10) println(largests)
-
修改前一个函数,返回最大的输出对应的输入。举例来说,largestAt(fun:(Int)=>Int,inputs:Seq[Int])应该返回5。不得使用循环或递归
def largest1(fun:(Int)=>Int,inputs:Seq[Int]):Int={ inputs.reduceLeft((x:Int,y:Int)=>if(fun(x) > fun(y)) x else y) } //调用此函数 val largests1 = largest1((x:Int)=>10*x-x*x,1 to 10) println(largests1)
List和map集合
复习一遍java集合
Collection | ||
---|---|---|
List | ||
ArrayList | ||
LinkedList | ||
Set | ||
Hashset | ||
TreeSet | ||
Map | ||
HashMap | 效率高,安全性低,因为它线程异步,允许键和值为null | |
HashTable | 效率低,安全性高,因为它线程同步,不允许键和值为null | |
LinkedHashMap | 添加顺序与出来的顺序相同 |
列表(List)
在scala中列表要么是空表(Nil),要么是一个head+tail,tail又是一个列表
val li = List(2,3,4,5,6,7,8)
println(li.head)//2
println(li.tail)//List(3, 4, 5, 6, 7)
val lb = Nil
println(lb)//List()
//判断集合是否为空
println(li.isEmpty)
增加:
注意: 不管是增加删除,都会产生一个新的列表,因为scala中的List是不可变的集合,不能被更改
//在列表li的尾部添加另外一个列表B,组成一个新的列表
val li1 = li.++(List(10,12,13))
println(li1)//List(2, 3, 4, 5, 6, 7, 10, 12, 13)
//在列表li的首部添加另外一个列表B,组成一个新的列表
val li2 = li.++:(List(14,15,16))
println(li2)//List(14, 15, 16, 2, 3, 4, 5, 6, 7)
//在列表li的尾部添加一个元素,组成一个新的列表
val li3 = li.:+(8)
println(li3)//List(2, 3, 4, 5, 6, 7, 8)
//在列表li的首部添加一个元素,组成一个新的列表
val li4 = li.+:(9)
println(li4)//List(9, 2, 3, 4, 5, 6, 7)
删除
//删除List的前n个元素(首部开始删除),并组合成一个新的列表
val li5 = li.drop(2)
println(li5)//List(4, 5, 6, 7)
//删除list的后n个元素(尾部开始删除),并组合成一个新的列表
val li6 = li.dropRight(2)
println(li6)//List(2, 3, 4, 5)
//逐个匹配去除符合条件的元素,直到不符合条件,之后的元素不再判断,组成一个新的列表,如果第一个就不符合,一个都不删
val li7 = li.dropWhile(_ > 5)
println(li7)//List(2, 3, 4, 5, 6, 7)
val li8 = li.dropWhile(_ < 5)
println(li8)//List(5, 6, 7)
其他常见操作
//根据下标获取元素
val s = li(0)
println(s)//2
//获取列表前5个元素
val li9 = li.take(5)
println(li9)
//获取满足条件的元素,直到不符合条件,之后的元素不再判断,如果第一个就不符合,就获取不到
val li10 = li.takeWhile(_ > 3)
println(li10)//List()
val li11 = li.takeWhile(_ < 3)
println(li11)//List(2)
//将集合变为字符串,中间以""隔开
val str = li.mkString("")
println(str)//2345678
//获取满足条件的元素的个数
val c = li.count(_ % 2 == 0)
println(c)//4
//::操作符从给定的头部和尾部创建一个新的列表
val fruit = "apples" :: ("oranges" :: ("pears" :: Nil))
println(fruit)//List(apples, oranges, pears)
//求list中的所有元素的和(必须是整形列表,其他类型的会报错)
val sum = li.sum
println(sum)
Set集合
Set集合不是重复元素的集合,不保留元素插入的顺序
val set1 = Set(1,2,3,2)
println(set1)
//添加元素
val set2 = set1+4
println(set2)
//遍历
set2.foreach(println(_))
//排序Set
val set3 = SortedSet(1,2,3,4,6,5)
println(set3)//TreeSet(1, 2, 3, 4, 5, 6)
//保留插入顺序
val set4 = mutable.LinkedHashSet(1,2,3,4,6,5)
println(set4)//Set(1, 2, 3, 4, 6, 5)
推荐阅读
-
Java基础知识回顾之四 ----- 集合List、Map和Set
-
java基础语法集合框架与泛型(List和Set)
-
【java读书笔记】——Collection集合之六大接口(Collection、Set、List、Map、Iterator和Comparable)
-
Python中的list(列表)、tuple(元组)、dict(字典)和set(集合)
-
Nodejs函数声明、调用、箭头函数、高阶函数、Set集合、事件处理机制、全局对象
-
List和Set集合
-
JAVA集合框架(二)-List和Set
-
java集合框架以及collection接口,list集合map集合和set集合
-
集合框架 List,Set,Map和泛型
-
java集合,List,Set和Map全面总结