res6: list[int] = list(60, 70, 80, 90, 100)
###### 5、排序 sort
在scala集合中,可以使用以下几种方式来进行排序
* sorted默认排序
* sortby指定字段排序
* sortwith自定义排序
###### 1、sorted默认排序
//定义一个list集合
scala> val list=list(5,1,2,4,3)
list: list[int] = list(5, 1, 2, 4, 3)
//默认就是升序
scala> list.sorted
res30: list[int] = list(1, 2, 3, 4, 5)
//生成新的list;原list不变
scala> list
res5: list[int] = list(5, 1, 2, 4, 3)
###### 2、sortby指定字段排序
根据传入的函数转换后,再进行排序
def sortby[b](f: (a) ⇒ b): list[a]
| sortby方法 | api | 说明 |
| --- | --- | --- |
| 泛型 | [b] | 按照什么类型来进行排序 |
| 参数 | f: (a) ⇒ b | 传入函数对象,接收一个集合类型的元素参数 返回b类型的元素进行排序 |
| 返回值 | list[a] | 返回排序后的列表 |
//定义一个list集合
scala> val list=list(“1 hadoop”,“3 flink”,“2 spark”)
list: list[string] = list(1 hadoop, 3 flink, 2 spark)
//按照单词的首字母进行排序
scala> list.sortby(x=>x.split(" ")(1))
res33: list[string] = list(3 flink, 1 hadoop, 2 spark)
reverse可以反转
###### 3、sortwith自定义排序
自定义排序,根据函数来定义排序规则
def sortwith(lt: (a, a) ⇒ boolean): list[a]
| sortwith方法 | api | 说明 |
| --- | --- | --- |
| 参数 | lt: (a, a) ⇒ boolean | 传入一个比较大小的函数对象,接收两个集合类型的元素参数,返回两个元素大小,小于返回true,大于返回false |
| 返回值 | list[a] | 返回排序后的列表 |
scala> val list = list(2,3,1,6,4,5)
a: list[int] = list(2, 3, 1, 6, 4, 5)
//降序
scala> list.sortwith((x, y)=>x>y)
res35: list[int] = list(6, 5, 4, 3, 2, 1)
list5.sortwith(_ > _)
//升序
scala> list.sortwith((x,y)=>x<y)
res36: list[int] = list(1, 2, 3, 4, 5, 6)
//字典序升序
list(“hive”, “hive”, “hadoop”, “spark”).sortwith(.compareto() < 0)
###### 6、分组 groupby
首先集合的元素得是kv对的;如果要将数据按照某值分组来进行统计分析,就需要使用到分组方法groupby表示按照函数将列表分成不同的组
def groupby[k](f: (a) ⇒ k): map[k, list[a]]
| groupby方法 | api | 说明 |
| --- | --- | --- |
| 泛型 | [k] | 分组字段的类型 |
| 参数 | f: (a) ⇒ k | 传入一个函数对象,接收集合元素类型的参数 返回一个k类型的key,这个key会用来进行分组,相同的key放在一组中 |
| 返回值 | map[k, list[a]] | 返回一个映射,k为分组字段,list为这个分组字段对应的一组数据 |
scala> val a = list(“张三”->“男”, “李四”->“女”, “王五”->“男”)
a: list[(string, string)] = list((张三,男), (李四,女), (王五,男))
// 按照性别分组
scala> a.groupby(_._2)
res0: scala.collection.immutable.map[string,list[(string, string)]] = map(男 -> list((张三,男), (王五,男)),
女 -> list((李四,女)))
// 将分组后的映射转换为性别/人数元组列表
scala> res0.map(x => x._1 -> x._2.size)
res3: scala.collection.immutable.map[string,int] = map(男 -> 2, 女 -> 1)
//求每个省份有多少人
val b = list(“张三”->(“男”, “北京”), “李四”->(“女”, “河北”), “王五”->(“男”, “北京”))
scala> b.groupby(_._2._2).map(x => (x._1, x._2.size))
res14: scala.collection.immutable.map[string,int] = map(北京 -> 2, 河北 -> 1)
###### 7、聚合 reduce
reduce表示将列表,传入一个函数进行聚合计算
def reduce[a1 >: a](op: (a1, a1) ⇒ a1): a1
| reduce方法 | api | 说明 |
| --- | --- | --- |
| 泛型 | [a1 >: a] | (下界)a1必须是集合元素类型的父类或本类型 |
| 参数 | op: (a1, a1) ⇒ a1 | 传入函数对象,用来不断进行聚合操作 第一个a1类型参数为当前聚合后的变量,第二个a1类型参数为当前要进行聚合的元素 |
| 返回值 | a1 | 列表最终聚合为一个元素 |
scala> val a = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
a: list[int] = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> a.reduce((x,y) => x + y)
res2: int = 55
// 第一个下划线表示第一个参数,就是历史的聚合数据结果
// 第二个下划线表示第二个参数,就是当前要聚合的数据元素
scala> a.reduce(_ + _)
res3: int = 55
// 与reduce一样,从左往右计算
scala> a.reduceleft(_ + _)
res4: int = 55
// 从右往左聚合计算
scala> a.reduceright(_ + _)
res5: int = 55
###### 8、折叠 fold
fold与reduce很像,但是多了一个指定初始值参数
def fold[a1 >: a](z: a1)(op: (a1, a1) ⇒ a1): a1
| reduce方法 | api | 说明 |
| --- | --- | --- |
| 泛型 | [a1 >: a] | (下界)a1必须是集合元素类型的父类或本类型 |
| 参数1 | z: a1 | 初始值 |
| 参数2 | op: (a1, a1) ⇒ a1 | 传入函数对象,用来不断进行折叠操作 第一个a1类型参数为当前折叠后的变量,第二个a1类型参数为当前要进行折叠的元素 |
| 返回值 | a1 | 列表最终折叠为一个元素 |
//定义一个list集合
scala> val a = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
a: list[int] = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
//求和
scala> a.sum
res1: int = 55
//给定一个初始值,,折叠求和
scala> a.fold(0)(+)
res2: int = 55
scala> a.fold(10)(+)
res3: int = 65
//从左往右
scala> a.foldleft(10)(+)
res4: int = 65
//从右往左
scala> a.foldright(10)(+)
res5: int = 65
//fold和foldlet效果一致,表示从左往右计算
//foldright表示从右往左计算
##### 二、高阶函数
高阶函数就是使用函数值作为参数,或者返回值为函数值的“函数”和“方法“。
###### 1、函数值作为参数
//定义一个数组
scala> val array=array(1, 2, 3, 4, 5)
array: array[int] = array(1, 2, 3, 4, 5)
//定义一个函数
scala> val func = (x: int) => x*10
func: int => int =
//完整的写法
val func: int => int = {
x => x*10
}
//函数作为参数传递到方法中
scala> array.map(func)
res0: array[int] = array(10, 20, 30, 40, 50)
###### 2、匿名函数
一个没有名称的函数,可以直接作为参数传递到方法中
//定义一个数组
scala> val array=array(1, 2, 3, 4, 5)
array: array[int] = array(1, 2, 3, 4, 5)
//定义一个没有名称的函数----匿名函数
scala> array.map(x => x*10)
res1: array[int] = array(10, 20, 30, 40, 50)
//简写写法
array.map(_ * 10)
###### 3、柯里化
方法可以定义多个参数列表,当使用较少的参数列表调用多参数列表的方法时,会产生一个新的函数,该函数接收剩余的参数列表作为其参数。这被称为柯里化。
scala> def add1(x: int, y: int): int = x + y
add1: (x: int, y: int)int
scala> add1(1, 2)
res2: int = 3
scala> def add2(x: int) = (y: int) => x + y
add2: (x: int)int => int
scala> val func1 = add2(2)
func1: int => int =
scala> func1(3)
res3: int = 5
//直接写
scala> add2(2)(3)
res4: int = 5
//柯里化的函数写法
scala> def add3(x: int)(y: int) = x + y
add3: (x: int)(y: int)int
//直接使用
scala> add3(2)(3)
res6: int = 5
//又一个示例,练习一下这多种写法
scala> def getaddress(a:string):(string,string)=>string={
| (b:string,c:string)=>a+“-”+b+“-”+c
| }
getaddress: (a: string)(string, string) => string
scala> val f1=getaddress(“china”)
f1: (string, string) => string =
scala> f1(“hangzhou”, “xihu”)
res7: string = china-hangzhou-xihu
//这里也可以这样去定义方法
scala> def getaddress(a:string)(b:string,c:string): string={
| a+“-”+b+“-”+c
| }
getaddress: (a: string)(b: string, c: string)string
//调用
scala> getaddress(“china”)(“hangzhou”, “xihu”)
res3: string = china-hangzhou-xihu
scala> val func = getaddress(“china”) _
func: (string, string) => string =
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
=> string =
[外链图片转存中…(img-do66u0hq-1714550516998)]
[外链图片转存中…(img-d5jqrblc-1714550516999)]
[外链图片转存中…(img-xdcx1gwv-1714550516999)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
发表评论