目录
一、面向函数编程
二、函数类型
三、函数作为参数用法
1、用函数作为参数
2、匿名函数和简化
3、高阶函数的应用foreach
4、map函数
四、函数做为返回值
五、map函数和fliter函数
六、集合(list,set,map,Tuple)
1、list:有序不唯一
2、set:无序唯一
3、Tuple 元组:固定长度集合
4、map:kv结构数据
面向函数编程: 将一个函数传来传去 --- 高阶函数
1、以函数作为参数
2、以函数作为返回值
需要明确函数的类型
1、函数的类型和函数名无关
2、函数类型油参数类型和返回值类型决定
例:
def fun1(str: String): Int = {
str.toInt
}
fun1是一个参数为String返回值为Int类型的函数
表达函数类型的简写:String => Int
val f: String => Int = fun1
println(f("200"))
表名f是一个参数为string类型,返回值为Int类型的函数,fun1赋给f
//以函数作为参数
def fun(f: String => Int): Unit = {
val i: Int = f("100")
println(i)
}
//定义一个参数为String、返回值为Int类型的函数
def f1(Str: String): Int = Str.toInt + 1000
fun(f1) //函数f1作为参数
//lambda 表达式:匿名函数
fun((s: String) => {
s.toInt
})
//简写
//大括号可以省略
fun((s: String) =>
s.toInt
)
//Scala可以自动判断参数类型
fun(s => s.toInt)
//因为s在后面语句只使用了一次,所以用下划线代替
fun(_.toInt)
//foreach:循环数组,按照顺序将数组匀速一个一个传给后面的函数
val array: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
//创建一个函数把foreach传出来的数输出
def f5(i: Int): Unit = println(i)
array.foreach(f5)
//可用匿名函数简写
array.foreach((i:Int)=>println(i))
//省略类型
array.foreach(i=>println(i))
//下划线代替变量
array.foreach(println(_))
//因为println是一个参数为Any 没有返回值的函数
//foreach需要一个参数为Int没有返回值的函数
// 同时Int是Any的子类
//这里也可以使用多态
//所以可以直接将println穿给foreach
array.foreach(println)
def main(args: Array[String]): Unit = {
//将数组中每个元素都加1
val array: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
//循环的做法
var i = 0
while (i < array.length) {
array(i) += 1
i += 1
}
array.foreach(println)
/*
scala 的方式
map:循换数组,将数组的元素一个一个传递给后面的函数,函数的返回值是一个新的数组
*/
val array1: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
val array2: Array[Int] = array1.map((i: Int) => i + 1)
array2.foreach(println)
}
def fun(): String => Int = {
println("fun被调用")
//在函数中定义一个函数作为返回值
def f(str:String):Int = {
println("f被调用")
str.toInt
}
//返回一个函数
f
}
//调用fun,返回一个函数
val ff: String => Int = fun()
//调用返回的函数
ff("100")
println(ff("100"))
fun被调用
f被调用
f被调用
100
获取文件中每一行的学号
val array: Array[String] = Source
.fromFile("data/students.txt") //读取文件
.getLines() //获取所有行
.toArray //转换成数组
val strings: Array[String] = array.map((student: String) => {
val s: Array[String] = student.split(",")
s(0)
})
strings.foreach(println)
获取文件所有文科一班的
/**
* filter: 将数组中的元素一个一个传递给后面的函数
* 如果函数返回True保留数据
* 如果函数返回False过滤数据
*/
val strings1: Array[String] = array.filter((student: String) => {
val s1: Array[String] = student.split(",")
"文科一班".equals(s1(4))
})
strings1.foreach(println)
(1)基本操作(所有集合都类似)
val list = List(1, 2, 3, 4, 5, 6, 6, 7, 8, 9)
//通过下标获取数据
println(list(4))
//获取头
println(list.head)
//获取最后一个元素
println(list.last)
//取前面几个元素
println(list.take(2))
//获取不包含第一个元素的所有元素
println(list.tail)
//判断是否为空
println(list.isEmpty)
//返回集合,返回一个倒序集合
println(list.reverse)
//去重
println(list.distinct)
//将集合构建成一个字符串,指定分割方式
//和split相反
println(list.mkString(","))
//判断是否包含某一个元素,返回Boolean
println(list.contains(1))
(2)map、filter、sortBy、flatMap、groupBy
map: 将集合中的元素一个一个传递给后面的函数,函数的返回值构建成一个新的集合 filter : 将集合中元素一个一个传递给后面的函数,如果函数返回True保留数据,如果函数返回False过滤数据 sortBy: 指定一个字段对数据进行排序, 默认是升序 flatMap : 将一行数据拆分成多行数据,返回一个集合 groupBy : 指定一个字段进行分组,返回一个Map结构的集合
//map
val list = List(1, 2, 3, 4, 5, 6, 6, 7, 8, 9)
val list2: List[Int] = list.map((i: Int) => i + 100)
println(list2)
//结果:List(101, 102, 103, 104, 105, 106, 106, 107, 108, 109)
//fliter
//取出所有的奇数
val filterList: List[Int] = list.filter((i: Int) => {
i % 2 == 1
})
println(filterList)
//结果:List(1, 3, 5, 7, 9)
//sortBy
val list3 = List(1, 2, 3, 1, 23, 12, 412, 3, 2, 12, 321, 4, 12, 312)
val sortList: List[Int] = list3.sortBy((i: Int) => -i)//默认升序,指定字段加负号,为降序
println(sortList)
//结果:List(412, 321, 312, 23, 12, 12, 12, 4, 3, 3, 2, 2, 1, 1)
//flatMap
val lines: List[String] = List("java,spark,hadoop", "hadoop,spark,hive", "scala,hive,java,hadoop")
val words: List[String] = lines.flatMap((line: String) => line.split(","))
words.foreach(println)
//结果:java
spark
hadoop
hadoop
spark
hive
scala
hive
java
hadoop
val list5 = List(1, 2, 3, 4, 1, 1, 2, 4, 4, 1, 2, 4, 4, 1)
val groupBy: Map[Int, List[Int]] = list5.groupBy((i: Int) => i)
groupBy.foreach(println)
//结果:
(2,List(2, 2, 2))
(4,List(4, 4, 4, 4, 4))
(1,List(1, 1, 1, 1, 1))
(3,List(3))
/**
* Set: 唯一无序
* 常用的map,flatMap,filter groupBy都有
* 和顺序相关的方法再set集合中没有
*/
//不可变的集合
val set = Set(1, 2, 2, 1, 2, 2, 3, 4)
println(set) //自动去重
println(set.mkString(",")) //转换为字符串
//集合运算
val s1 = Set(1, 2, 3, 4, 5, 6)
val s2 = Set(4, 5, 6, 7, 8, 9)
println(s1 & s2) //交集
println(s1 | s2) //并集
println(s1 &~ s2) //差集
//结果:
Set(1, 2, 3, 4)
1,2,3,4
Set(5, 6, 4)
Set(5, 1, 6, 9, 2, 7, 3, 8, 4)
Set(1, 2, 3)
/**
* 元组: 固定长度集合
* 可以通过_获取数据, 相比较于数组,元组不存在下标越界问题
* 元组中的元素上限是22个
*/
val t = (1, 2, 3, 4, 5, 10)
println(t._1)
//结果:1
//->: 构建二元组的简写
val map = Map(("001", "张三"), ("002", "李四"), ("003", "王五"), "004" -> "赵六")
println(map)
//可以通过key获取value
println(map("001")) //如果key不存在会报错
println(map.getOrElse("007", "默认值")) //如果key不存在返回默认值
println(map.keys)//获取所有的key
println(map.values) //所有value
//foreach: 将map集合中的元素传递给后面的函数,以元组的形式传递给后面的函数
map.foreach((kv: (String, String)) => {
val key: String = kv._1
val value: String = kv._2
println(s"$key\t$value")
})
/**
* map:将map集合中的袁术一个一个传递给后面的函数
* 如果函数返回一个二元组,会被构建成一个新的mao
* 如果函数返回一个非二元组,会被构建出一个List集合
*/
val map1: Map[String, String] = map.map((kv: (String, String)) => {
//获取key
val key: String = kv._1
//获取value
val value: String = kv._2
//在value上拼接一个1
val name: String = value + "1"
//返回一个元组
(key, name)
})
println(map1)
//结果:
Map(001 -> 张三, 002 -> 李四, 003 -> 王五, 004 -> 赵六)
张三
默认值
Set(001, 002, 003, 004)
MapLike(张三, 李四, 王五, 赵六)
001 张三
002 李四
003 王五
004 赵六
Map(001 -> 张三1, 002 -> 李四1, 003 -> 王五1, 004 -> 赵六1)