集合简介

1)说明
(1)Scala的集合有三大类:序列Seq、集Set、映射Map,所有的集合都扩展自Iterable特质。
(2)对于几乎所有的集合类,Scala都同时提供了可变不可变的版本,分别位于以下两个包
不可变集合:scala.collection.immutable
可变集合: scala.collection.mutable
2)案例实操
(1)Scala不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。
(2)可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。

  1. object TestList {
  2. def main(args: Array[String]): Unit = {
  3. //不可变List
  4. val immutableList: List[Int] = List(1, 2, 3, 4, 5)
  5. //对不可变List进行修改,在头部添加一个元素0
  6. val newImmutableList: List[Int] = 0 +: immutableList
  7. println(immutableList)
  8. println(newImmutableList)
  9. //可变List
  10. val mutableList: ListBuffer[Int] = ListBuffer(1, 2, 3, 4, 5)
  11. //对可变List进行修改,在头部添加一个元素0
  12. val newMutableList: ListBuffer[Int] = 0 +=: mutableList
  13. println(mutableList)
  14. println(newMutableList)
  15. }
  16. }

不可变集合继承图

image.png
1)Set、Map是Java中也有的集合
2)Seq是Java没有的,我们发现List归属到Seq了,因此这里的List就和Java不是同一个概念了
3)我们前面的for循环有一个 1 to 3,就是IndexedSeq下的Vector
4)String也是属于IndexeSeq
5)我们发现经典的数据结构比如Queue和Stack被归属到LinerSeq
6)大家注意Scala中的Map体系有一个SortedMap,说明Scala的Map可以支持排序
7)IndexSeq和LinearSeq的区别:
(1)IndexSeq是通过索引来查找和定位,因此速度快,比如String就是一个索引集合,通过索引即可定位
(2)LineaSeq是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找

可变集合继承图

image.png

集合符号总结:

  • 带+与带-的区别:

    带+是添加元素
    带-是删除元素(不可变一般没有-号)

  • 一个+/-与两个+/-的区别:

    一个+/-是添加/删除单个元素
    两个+/-是添加/删除指定集合所有元素

  • 冒号在前与冒号在后以及不带冒号的区别:

    冒号在前是将元素添加在集合最末尾
    不带冒号是将元素添加在集合最末尾
    冒号在后是将元素添加在集合最前面

  • 带=与不带=的区别

    带=是修改集合本身(不可变一般没有=号)
    不带=是生成一个新集合,原集合没有改变

    有序集合:【数组、list、队列】

  • update/updated方法修改元素

    可变的不需要update/updated方法,直接通过角标修改数据
    不可变的需要update/updated方法才能修改数据
    update:修改集合本身
    updated:生成一个新的集合,原集合没有改变

  • 不可变与可变,可相互转换

    无序集合:【map、set】

    set

  • 无法修改元素

    map

  • 不可变map,不可删除元素

  • 可变map,可删除

集合分类

数组

不可变数组

_ 不可变数组创建:
1、通过new创建: new Array元素类型
2、通过apply方法: Array元素类型
添加数据
删除数据
获取数据: 数组名(角标)
修改数据: 数组名(角标) = 值

  1. package tcode.chapter07
  2. object $01_ImmutableArray {
  3. def main(args: Array[String]): Unit = {
  4. //1、通过new创建: new Array[元素类型](数组的长度)
  5. val arr = new Array[String](10)
  6. println(arr.toList)
  7. //2、通过apply方法: Array[元素类型](初始元素,...)
  8. val arr2 = Array[Int](10,3,7,9,20)
  9. println(arr2.toList)
  10. //3、添加元素
  11. //添加单个元素
  12. val arr3 = arr2.+:(40)
  13. println(arr3.toList)
  14. println(arr2.toList)
  15. println( arr2.eq(arr3) )
  16. val arr4 = arr2.:+(50)
  17. println(arr4.toList)
  18. //添加一个整个集合
  19. val arr5 = arr2.++(Array(100,200,300))
  20. println(arr5.toList)
  21. val arr6 = arr2.++:(Array(600,700,800))
  22. println(arr6.toList)
  23. //2、删除
  24. //3、获取元素
  25. println(arr2(0))
  26. //4、修改元素
  27. arr2(0) = 100
  28. println(arr2.toList)
  29. arr2.update(1,30) // 只改变原集合,不会生成新集合
  30. println(arr2.toList)
  31. //不可变转可变
  32. val arr10 = arr2.toBuffer
  33. println(arr10)
  34. }
  35. }

可变数组


可变数组的创建:
1、通过new: new ArrayBuffer元素类型
2、通过apply方法: ArrayBuffer元素类型

  1. package tcode.chapter07
  2. import scala.collection.mutable.ArrayBuffer
  3. object $02_MutbaleArray {
  4. def main(args: Array[String]): Unit = {
  5. //1、通过new: new ArrayBuffer[元素类型]()
  6. val arr = new ArrayBuffer[Int]()
  7. //2、通过apply方法: ArrayBuffer[元素类型](初始元素,...)
  8. val arr2 = ArrayBuffer[Int](10,4,5,2,9)
  9. println(arr.toList)
  10. println(arr2.toList)
  11. //添加元素
  12. val arr3 = arr2.+:(10)
  13. println(arr3.toList)
  14. println(arr2.toList)
  15. val arr4 = arr2.:+(30)
  16. println(arr4.toList)
  17. arr2.+=(60)
  18. println(arr2.toList)
  19. arr2.+=:(90)
  20. println(arr2.toList)
  21. //添加一个集合
  22. val arr5 = arr2.++( Array(100,200) )
  23. println(arr5.toList)
  24. val arr6 = arr2.++:( Array(100,200) )
  25. println(arr6.toList)
  26. arr2.++=( Array(500,600) )
  27. println(arr2.toList)
  28. arr2.++=:( Array(500,600) )
  29. println(arr2.toList)
  30. //删除
  31. val arr7 = arr2.-( 500 )
  32. println(arr7.toList)
  33. arr2.-=( 600 )
  34. println(arr2.toList)
  35. val arr8 = arr2.-- ( Array(500,600,600))
  36. println(arr8.toList)
  37. arr2.--=( Array(500,600,2,9) )
  38. println(arr2.toList)
  39. arr2.remove(0,3)
  40. //获取元素
  41. println(arr2(0))
  42. //修改元素
  43. arr2(0)=900
  44. println(arr2.toList)
  45. arr2.+=(500)
  46. arr2.+=(500)
  47. arr2.+=(600)
  48. println(arr2.toList)
  49. //可变转不可变
  50. val arr10 = arr2.toArray
  51. println(arr10.toList)
  52. //多维数组的创建
  53. val arr11 = Array.ofDim[Int](3,4)
  54. println(arr11.length)
  55. println(arr11(0).length)
  56. }
  57. }

Seq集合(List)

不可变list

  1. 创建:<br /> 1apply方法: List[元素类型](初始元素,。。。)<br /> 2、初始元素 :: 初始元素 :: ... :: 不可变List/Nil(空的不可变list)<br />添加位置:看元素处于::的位置<br /> :: 最右边必须是不可变List或者是Nil<br /> Nil是空集合,NilList的关系类似NullString的关系<br /> ** Nil一般可以用于给不可变List变量赋予初始值, Nil给不可变List变量赋予初始值的时候**必须指定变量类型<br /> <br /> :: ::: 的区别:<br /> ::是添加单个元素<br /> ::: 是添加一整个集合(arraylist等)所有元素

list转array
println(list10.toBuffer)

  1. package tcode.chapter07
  2. object $03_ImmutableList {
  3. def main(args: Array[String]): Unit = {
  4. //1、apply方法: List[元素类型](初始元素,。。。)
  5. val list = List[Int](10,3,6,7,2)
  6. var list2:List[Int] = Nil
  7. list2= list
  8. //2、初始元素 :: 初始元素 :: ... :: List/Nil
  9. val list3 = 10 :: 5 :: 6 :: Nil
  10. println(list3)
  11. //3、添加元素
  12. val list4 = list3.+:(20)
  13. println(list4)
  14. val list5 = list3.:+(40)
  15. println(list5)
  16. val list6 = 40 :: list3
  17. println(list6)
  18. val list7 = list3.++(Array(10,20,30))
  19. println(list7)
  20. val list8 = list3.++:(Array(10,2030))
  21. println(list8)
  22. val list9 = List(50,60,70) ::: list3
  23. println(list9)
  24. val list10 = List(50,60,70) :: list3
  25. println(list10) // 两个冒号的结果是List(List(10,20,30),10,5,6)
  26. //删除:无
  27. //获取元素
  28. println(list9(0))
  29. //修改元素
  30. //list9(0)=100,没办法通过这种方式获取值
  31. //println(list9)
  32. val list10 = list9.updated(0,100)// 获取给新list,0:索引,100:值
  33. println(list9)
  34. println(list10)
  35. //List转Array
  36. println(list10.toBuffer)
  37. }
  38. }

可变list

  1. package tcode.chapter07
  2. import scala.collection.mutable.ListBuffer
  3. object $04_MutableList {
  4. /**
  5. * 创建可变List: ListBuffer[元素类型](初始元素,...)
  6. */
  7. def main(args: Array[String]): Unit = {
  8. val list = ListBuffer[Int](10,20,3,5,9)
  9. println(list)
  10. //添加元素
  11. val list2 = list.+:(30)
  12. println(list2)
  13. val list3 = list.:+(50)
  14. println(list3)
  15. list.+=(100)
  16. println(list)
  17. list.+=:(300)
  18. println(list)
  19. val list4 = list.++(Array(100,200,300))
  20. println(list4)
  21. val list5 = list.++:(Array(100,200,300))
  22. println(list5)
  23. list.++=(List(11,22,33))
  24. println(list)
  25. list.++=:(List(44,55,66))
  26. println(list)
  27. //删除元素
  28. val list6 = list.-( 55 )
  29. println(list6)
  30. list.-=(66)
  31. println(list)
  32. val list7 = list.--(List(44,300,11))
  33. println(list7)
  34. list.--=(List(10,20,22,33))
  35. println(list)
  36. //获取元素
  37. println(list(0))
  38. //修改元素
  39. list(0)=100
  40. println(list)
  41. //可变转不可变
  42. println(list.toList)
  43. }
  44. }

set集合

不可变set

  1. package tcode.chapter07
  2. object $05_ImmutableSet {
  3. //Set的特性: 无序,不重复
  4. //
  5. def main(args: Array[String]): Unit = {
  6. //创建Set: Set[元素类型](初始元素,...)
  7. val set = Set[Int](10,2,2,5,1,9)
  8. println(set)
  9. //添加元素
  10. val set2 = set.+(20)
  11. println(set2)
  12. val set3 = set.++(List(100,94,20,99))
  13. println(set3)
  14. val set4 = set.++:(List(100,94,20,99))
  15. println(set4)
  16. //删除元素
  17. val set5 = set.-(10)
  18. println(set5)
  19. val set6 = set.--(List(5,1,9))
  20. println(set6)
  21. //获取元素,只能通过遍历获得
  22. // println(set6(10)) // 返回true/false
  23. for(e<- set){
  24. println(e)
  25. }
  26. //修改元素,无法修改
  27. }
  28. }

可变set

  1. package tcode.chapter07
  2. import scala.collection.mutable
  3. object $06_MutableSet {
  4. def main(args: Array[String]): Unit = {
  5. //创建: mutable.Set[元素类型](初始元素,。。。。)
  6. val set = mutable.Set[Int](10,3,7,2,9,20)
  7. println(set)
  8. //添加
  9. val set2 = set.+(100)
  10. println(set2)
  11. set.+=(100)
  12. println(set)
  13. val set3 = set.++(List(200,87,65))
  14. println(set3)
  15. val set4 = set.++:(List(200,87,65))
  16. println(set4)
  17. set.++=(List(200,87,65))
  18. println(set)
  19. //删除
  20. val set5 = set.-(2)
  21. println(set5)
  22. set.-=(100)
  23. println(set)
  24. val set6 = set.--(List(2,3,7))
  25. println(set6)
  26. set.--=(List(2,3,7))
  27. println(set)
  28. //修改元素
  29. //set.update(200,false),这个update执行的是新增操作,无法修改元素,true则添加元素
  30. //println(set)
  31. }
  32. }

元祖:

/*
元组创建:
1、通过()方式创建: (初始元素,…)
2、通过->方式创建[只能在二元元组使用]: K->V
scala中二元元祖对应KV键值对
元组中最多只能存放22个元素
元组一旦定义就不可变[元素不可变,长度不可变]
元组获取值: 元组名._角标 [元组的角标从1开始] 如 : r._1
*/

  1. package tcode.chapter07
  2. object $07_Tuple {
  3. def main(args: Array[String]): Unit = {
  4. //元组创建:
  5. val t1 = ("zhangsan",20,"shenzhen")
  6. val t2 = "zhagnsan"->20
  7. println(t1)
  8. println(t2)
  9. println(t1._1)
  10. val logs = List("1 zhangsan 20 shenzhen","2 wagnwu 30 beijing","3 zhaoliu 44 shenzhen")
  11. val persons = for(e<- logs) yield {
  12. val arr = e.split(" ")
  13. (arr(0),arr(1),arr(2).toInt,arr(3))
  14. }
  15. // persons: list((1,zhangsan,20,shenzhen),(。。。),(。。。))
  16. for(e<- persons){
  17. println(e._3)
  18. }
  19. val list2 = List[Region](
  20. new Region("宝安区",new School("宝安中学",new Clazz("大数据班",new Student("zhangsan",20)))),
  21. new Region("宝安区",new School("宝安中学",new Clazz("大数据班",new Student("wangwu",20)))),
  22. new Region("宝安区",new School("宝安中学",new Clazz("大数据班",new Student("zhaoliu",20))))
  23. )
  24. val ts = List[(String,(String,(String,(String,Int))))](
  25. ("宝安区",("宝安中学",("大数据班",("zhangsan",20)))),
  26. ("宝安区",("宝安中学",("大数据班",("wangwu",20)))),
  27. ("宝安区",("宝安中学",("大数据班",("zhaoliu",20))))
  28. )
  29. for(element<- ts){
  30. println( element._2._2._2._1 )
  31. }
  32. }
  33. class Region(name:String,school:School)
  34. class School(name:String,clazz:Clazz)
  35. class Clazz(name:String,stu:Student)
  36. class Student(name:String,age:Int)
  37. }

map集合

不可变map

  1. * 创建方式:<br /> * Map[K的类型,V的类型]( (K,V) ,..)<br /> * Map[K的类型,V的类型]( K->V ,..)<br /> * Option: 提醒外部当前返回结果有可能为空(防止空指针异常),需要进行处理<br /> * Some: 代表有值,值封装在Some中<br /> * None: 代表为空<br /> * Map取值通过getOrElse(key,默认值)[代表key如果在map中存在则取出对应的value值,如果不存在则返回默认值]
  1. package tcode.chapter07
  2. object $08_ImmutableMap {
  3. /**
  4. * 创建方式:
  5. * Map[K的类型,V的类型]( (K,V) ,..)
  6. * Map[K的类型,V的类型]( K->V ,..)
  7. * Option: 提醒外部当前返回结果有可能为空,需要进行处理
  8. * Some: 代表有值,值封装在Some中
  9. * None: 代表为空
  10. * Map取值通过getOrElse(key,默认值)[代表key如果在map中存在则取出对应的value值,如果不存在则返回默认值]
  11. *
  12. */
  13. def main(args: Array[String]): Unit = {
  14. val map = Map[String,Int]("aa"->1,"bb"->2,("cc",3) )
  15. //添加元素
  16. val map2 = map.+( "dd"->4 )
  17. println(map2)
  18. val map3 = map.++( List( ("ee",10),"oo"->20,"tt"->30,"ff"->20 ) )
  19. println(map3)
  20. val map4 = map.++:( List( ("ee",10),"oo"->20,"tt"->30,"ff"->20 ) )
  21. println(map4)
  22. //获取元素
  23. // map4.get("ee").get,可以通过get方法获取,但是返回类型是option类型,需要再通过get从some中获得,但是没什么意义
  24. println(map4.getOrElse("ee",0))
  25. //修改元素
  26. //map4("ee")=200 ,不可变map无法通过这种方式修改
  27. // updated方法:如果存在key则修改元素,如果不存在Key则不修改元素
  28. val map5 = map4.updated("ee",100)
  29. println(map4)
  30. // println(map5)
  31. // 删除元素:无
  32. }
  33. }

可变map

  1. package tcode.chapter07
  2. import scala.collection.mutable
  3. object $09_MutableMap {
  4. def main(args: Array[String]): Unit = {
  5. val map = mutable.Map[String,Int]("aa"->10,("bb",20),"tt"->50)
  6. //添加元素
  7. val map2 = map.+( "pp"->60 )
  8. println(map2)
  9. map.+=( "uu"->33 )
  10. println(map)
  11. val map4 = map.++( List( "rr"->10,"ll"->20 ))
  12. println(map4)
  13. val map5 = map.++:(List( "rr"->10,"ll"->20 ))
  14. println(map5)
  15. map.++=(List( "rr"->10,"ll"->20 ))
  16. println(map)
  17. map.put("zz",300)
  18. println(map)
  19. //删除,只需要删除key即可
  20. val map6 = map.-("uu")
  21. println(map6)
  22. map.-=("uu")
  23. println(map)
  24. val map7 = map.--(List("ll","aa","rr"))
  25. println(map7)
  26. map.--=(List("ll","aa","rr"))
  27. println(map)
  28. map.remove("zz")
  29. println(map)
  30. //获取元素
  31. println(map.getOrElse("bb", 200))
  32. //修改元素
  33. map("bb")=200
  34. println(map)
  35. map.update("bb",400)
  36. println(map)
  37. }
  38. }

队列

可变队列

  1. package tcode.chapter07
  2. import scala.collection.immutable.Queue
  3. object $10_ImmutableQueue {
  4. def main(args: Array[String]): Unit = {
  5. //创建: Queue[元素类型](初始元素,...)
  6. val q1 = Queue[Int](1,5,7,9,2)
  7. println(q1)
  8. //添加元素
  9. val q2 = q1.+:( 20 )
  10. println(q2)
  11. val q3 = q1.:+( 30 )
  12. println(q3)
  13. val q4 = q1.++(List(100,400,200))
  14. println(q4)
  15. val a5 = q1.++:(List(100,400,200))
  16. println(a5)
  17. val q6 = q1.enqueue(1000)
  18. println(q6)
  19. //删除,dequeue返回值为元祖(A, Queue[A])A为出列的元素,Queue[A]为剩余元素
  20. val r = q1.dequeue
  21. println(r._1)
  22. println(r._2)
  23. //获取元素
  24. println(q1(0))
  25. //修改元素
  26. //q1(0)=100 // 不可变无法通过下标修改
  27. //println(q1)
  28. val q9 = q1.updated(0,100)
  29. println(q9)
  30. }
  31. }

不可变队列

  1. package tcode.chapter07
  2. import scala.collection.mutable
  3. object $11_MutableQueue {
  4. def main(args: Array[String]): Unit = {
  5. //创建
  6. val queue = mutable.Queue[Int](10,2,5,8,20)
  7. //添加元素
  8. val queue2 = queue.+:( 30 )
  9. println(queue2)
  10. val queue3 = queue.:+(40)
  11. println(queue3)
  12. queue.+=(50)
  13. queue.+=:(70)
  14. println(queue)
  15. val queue4 = queue.++(List(100,300,200))
  16. val queue5 = queue.++:(List(100,300,200))
  17. queue.++=(List(100,300,200))
  18. println(queue4)
  19. println(queue5)
  20. println(queue)
  21. queue.enqueue(55,44,333)
  22. println(queue)
  23. //删除,dequeue返回值类型:元祖
  24. println(queue.dequeue())
  25. //获取元素
  26. println(queue(0))
  27. //修改元素
  28. queue(1)=222
  29. println(queue)
  30. queue.update(0,111)
  31. println(queue)
  32. }
  33. }

par并行集合

/*
并行集合: scala集合默认是单线程操作,如果想要多线程操作集合元素,需要使用并行集合
普通集合转并行集合: 集合名.par
/

  1. package tcode.chapter07
  2. object $12_Par {
  3. def main(args: Array[String]): Unit = {
  4. val list = List(1,2,5,8,20)
  5. list.foreach(x=>{
  6. println(s"${Thread.currentThread().getName} --- ${x}")
  7. } )
  8. println("-"*100)
  9. val list2 = list.par
  10. list2.foreach(x=>{
  11. println(s"${Thread.currentThread().getName} --- ${x}")
  12. } )
  13. }
  14. }

集合常用函数

基本属性操作

  1. package tcode.chapter07
  2. object $13_CollectionField {
  3. def main(args: Array[String]): Unit = {
  4. val list = List(1,5,3,7,10,2)
  5. //是否包含某个元素
  6. println(list.contains(100))
  7. //是否为空
  8. println(list.isEmpty)
  9. //获取集合长度
  10. println(list.length)
  11. println(list.size)
  12. //将集合转成字符串
  13. println(list)
  14. println(list.mkString("#"))
  15. }
  16. }

衍生集合

  1. package tcode.chapter07
  2. object $14_CollectionPar {
  3. def main(args: Array[String]): Unit = {
  4. val list = List(10,2,5,6,3,90,8,4,10)
  5. //去重 !!!
  6. println(list.distinct)
  7. //删除前多少个元素,保留剩余其他元素
  8. println(list.drop(3))
  9. //删除后多少个元素,保留剩余其他元素
  10. println(list.dropRight(3))
  11. //获取第一个元素 !!!
  12. println(list.head)
  13. //获取最后一个元素 !!!
  14. println(list.last)
  15. //获取除开最后一个元素的所有元素
  16. println(list.init)
  17. //反转 *****
  18. println(list.reverse)
  19. //获取子集合
  20. println(list.slice(0, 3))
  21. //滑窗 !!!
  22. //size: 窗口的长度
  23. // 内部是元祖,外部是list:List((),(),())
  24. //step: 滑动长度
  25. println(list.sliding(4, 3).toList)
  26. //获取除开第一个元素的所有元素
  27. println(list.tail)
  28. //获取前多少个元素 !!!
  29. println(list.take(3))
  30. //获取后多少个元素
  31. println(list.takeRight(3))
  32. //交集
  33. val list2 = List(1,2,3,4,5)
  34. val list3 = List(4,5,6,7,8)
  35. println(list2.intersect(list3))
  36. //并集
  37. println(list2.union(list3))
  38. //差集[A差B的结果就是A中有B中没有的元素]
  39. println(list2.diff(list3))
  40. //拉链
  41. val list4 = List("aa","bb","cc","dd")
  42. val list5 = List(10,20,30)
  43. val list6 = list4.zip(list5)
  44. println(list6)
  45. //反拉链
  46. println(list6.unzip)
  47. //将元素与角标拉链
  48. println(list4.zipWithIndex)
  49. }
  50. }

集合初级函数

聚合

list.max
list.min
list.sum
list.maxby
list.minby

排序

list.sorted
list.reverse
list.sortBy
list.sortWith

  1. package tcode.chapter07
  2. import scala.math.Ordering
  3. object $15_CollectionLowFunction {
  4. def main(args: Array[String]): Unit = {
  5. val list = List(10,3,5,7,2,20)
  6. //获取最大值
  7. println(list.max)
  8. //获取最小值
  9. println(list.min)
  10. //求得总和
  11. println(list.sum)
  12. //根据指定字段获取最大值
  13. //maxBy(func: 集合元素类型 => B )
  14. //maxBy是根据函数的返回值进行排序之后取最大元素
  15. //后续会将集合每个元素当做参数传递给函数,maxBy中的函数是集合有多少元素就调用多少次
  16. val list2 = List[(String,Int,Int)](
  17. ("zhangsan1",20,3000),
  18. ("zhangsan4",16,4000),
  19. ("zhangsan4",30,4000),
  20. ("zhangsan2",15,2500),
  21. ("zhangsan3",33,1500)
  22. )
  23. val func = (x:(String,Int,Int)) => x._2
  24. println(list2.maxBy(func))
  25. //直接传递函数值
  26. println(list2.maxBy((x:(String,Int,Int)) => x._2))
  27. //省略函数参数类型
  28. println(list2.maxBy((x) => x._2))
  29. //函数参数只有一个,()可以省略
  30. println(list2.maxBy( x => x._2))
  31. // 使用_代替
  32. println(list2.maxBy( _._2))
  33. //根据指定字段获取最小值
  34. //minBy(func: 集合元素类型=>B )
  35. //minBy是根据函数的返回值排序之后取最小值
  36. //后续会将集合每个元素当做参数传递给函数,minBy中的函数是集合有多少元素就调用多少次
  37. println(list2.minBy(x => {
  38. x._3
  39. }))
  40. //排序
  41. //1、直接根据元素本身排序,默认升序【sorted】
  42. val list3 = list.sorted
  43. println(list3)
  44. //降序
  45. println(list3.reverse)
  46. println(list2.sorted)
  47. //2、根据指定字段排序[sortBy],默认升序 *****
  48. //sortBy(func: 集合元素类型 => B )
  49. //sortBy是根据函数的返回值进行排序
  50. //后续会将集合每个元素当做参数传递给函数
  51. val ordering = new Ordering[Int]{
  52. override def compare(x: Int, y: Int): Int = {
  53. if(x>y) -1
  54. else if(x==y) 0
  55. else 1
  56. }
  57. }
  58. println(list2.sortBy(x => {
  59. x._3 // 一定要在花括号内(之前因可省略而删除)打断点才能看到函数体的值
  60. })(ordering))
  61. //3、根据自己比较排序 sortWith
  62. // 升序: 第一个参数>第二个参数
  63. // 降序: 第一个参数<第二个参数
  64. println(list.sortWith((x, y) => {
  65. x > y
  66. }))
  67. }
  68. }

集合高阶函数

过滤: filter(func: 集合元素类型=>Boolean)

  1. filter是针对每个元素操作,后续会将集合每个元素当做函数的参数值传入<br /> filter是集合有多少个元素就调用多少次<br /> filter保留是函数返回值为true的数据

映射: map(func: 集合元素类型=> B ),

其实就是:val func = 集合元素类型 => B , map(func)
map的应用场景: 一对一
map中的函数也是针对集合每个元素操作,后续会将集合每个元素当做函数的参数值传入
val B = A.map( ..) 此时B集合的长度=A集合的长度
map一般用于转换[值的转换、类型的转换]
一般用于抽出(集合)元素进行操作

压平: flatten

  1. flatten是针对集合嵌套集合的场景,会将第二层集合去掉<br /> flatten的场景: 一对多

压平转换类型 flatMap(func: 集合元素类型 => 集合) = map + flatten

  1. flatMap中的函数是针对集合每个元素进行操作,集合有多少个元素,函数就调用多少次<br /> flatMap的应用场景: 一对多<br /> flatMapflatten的区别:<br /> flatMap是先对元素进行转换之后再压平,flatten是直接压平不转换

遍历 foreach(func: 集合元素类型 => B ):Unit : 遍历

  1. foreach中的函数是针对集合每个元素操作<br /> foreachmap的区别:<br /> map有返回值,foreach是没有返回值

分组 groupBy(func: 集合元素类型=> K): 根据指定字段分组

  1. groupBy里面的函数是针对集合每个元素进行操作,groupBy分组是根据函数的返回值进行分组<br /> groupBy的结果是Map[K,V] K就是函数的返回值,也就是分组的key,V是分组的key对应原集合中的所有元素】

聚合reduce\fold

reduce(func: (集合元素类型,集合元素类型)=>集合元素类型): 从左向右计算

  1. reduce是对集合中所有元素进行聚合<br /> reduce函数第一个参数第一次计算的时候初始值 = 集合第一个元素,第N次计算的时候第一个参数的值 = N-1次的结果<br /> reduceRight(func: (集合元素类型,集合元素类型)=>集合元素类型): 从右向左计算<br /> reduceRight是对集合中所有元素进行聚合.<br /> reduceRight函数第二个参数第一次计算的时候初始值 = 集合最后一个元素,第N次计算的时候第二个参数的值 = N-1次的结果

fold(初始值)(func: (集合元素类型,集合元素类型)=>集合元素类型): 从左向右计算

  1. fold是对集合中所有元素进行聚合<br /> fold函数第一个参数第一次计算的时候初始值 = 指定默认值,第N次计算的时候第一个参数的值 = N-1次的结果<br /> foldRight(初始值)(func: (集合元素类型,集合元素类型)=>集合元素类型): 从右向左计算<br /> foldRight是对集合中所有元素进行聚合<br /> foldRight函数第二个参数第一次计算的时候初始值 = 指定默认值,第N次计算的时候第二个参数的值 = N-1次的结果
  1. package tcode.chapter07
  2. object $16_CollectionHightFunction {
  3. def main(args: Array[String]): Unit = {
  4. val list = List(10,2,5,6,7,9)
  5. //过滤: filter(func: 集合元素类型=>Boolean)
  6. // filter是针对每个元素操作,后续会将集合每个元素当做函数的参数值传入
  7. // filter是集合有多少个元素就调用多少次
  8. // filter保留是函数返回值为true的数据
  9. val list2 = list.filter(x=> {
  10. println(s"x=${x}")
  11. x%2==0
  12. })
  13. println(list2)
  14. //映射: map(func: 集合元素类型=> B )
  15. //map的应用场景: 一对一
  16. //map中的函数也是针对集合每个元素操作,后续会将集合每个元素当做函数的参数值传入
  17. //val B = A.map( ..) 此时B集合的长度=A集合的长度
  18. //map一般用于转换[值的转换、类型的转换]
  19. val list3 = List("spark","hadoop","flume","kafka")
  20. val list4 = list3.map( x => x.length )
  21. println(list4)
  22. //压平: flatten
  23. //flatten是针对集合嵌套集合的场景,会将第二层集合去掉
  24. //flatten的场景: 一对多
  25. val list5 = List[List[Int]](
  26. List(1,2),
  27. List(4,5),
  28. List(7,8)
  29. )
  30. val list6 = list5.flatten
  31. println(list6)
  32. val list7 = List[List[List[Int]]](
  33. List(
  34. List(1,2),
  35. List(5,6)
  36. ),
  37. List(
  38. List(7,8),
  39. List(9,10)
  40. )
  41. )
  42. val list8 = list7.flatten.flatten
  43. println(list8)
  44. val list9 = List("aa","cc")
  45. println(list9.flatten)
  46. //flatMap(func: 集合元素类型 => 集合) = map + flatten
  47. //flatMap中的函数是针对集合每个元素进行操作,集合有多少个元素,函数就调用多少次
  48. //flatMap的应用场景: 一对多
  49. //flatMap与flatten的区别:
  50. // flatMap是先对元素进行转换之后再压平,flatten是直接压平不转换
  51. val list10 = List("hadoop spark flume","kafka flink hello")
  52. // val list11 = list10.map(x=> x.split(" "))
  53. // val list12 = list11.flatten
  54. // println(list12)
  55. // 上面等价于:
  56. val list11 = list10.flatMap(x=>x.split(" "))
  57. println(list11)
  58. //结果:List(hadoop,spark,flume,kafka,flink,hello)
  59. //遍历:foreach(func: 集合元素类型 => B ):Unit : 遍历
  60. //foreach中的函数是针对集合每个元素操作
  61. //foreach与map的区别:
  62. // map有返回值,foreach是没有返回值
  63. list.foreach(x=>println(x))
  64. //groupBy(func: 集合元素类型=> K): 根据指定字段分组
  65. //groupBy里面的函数是针对集合每个元素进行操作,groupBy分组是根据函数的返回值进行分组
  66. //groupBy的结果是Map[K,V] 【K就是函数的返回值,也就是分组的key,V是分组的key对应原集合中的所有元素】
  67. val list13 = List( ("lisi","man","shenzhen"),("wangwu","woman","beijing"),("zhaoliu","man","beijing") )
  68. val map2 = list13.groupBy(x=> x._3)
  69. println(map2)
  70. //reduce
  71. //reduceRight
  72. //fold
  73. //foldRight
  74. //聚合
  75. //reduce(func: (集合元素类型,集合元素类型)=>集合元素类型): 从左向右计算
  76. //reduce是对集合中所有元素进行聚合
  77. //reduce函数第一个参数第一次计算的时候初始值 = 集合第一个元素,第N次计算的时候第一个参数的值 = 第N-1次的结果
  78. val result = list.reduce((agg,curr) => {
  79. println(s"agg=${agg} curr=${curr}")
  80. agg-curr
  81. })
  82. println(result)
  83. //reduceRight(func: (集合元素类型,集合元素类型)=>集合元素类型): 从右向左计算
  84. //reduceRight是对集合中所有元素进行聚合
  85. //reduceRight函数第二个参数第一次计算的时候初始值 = 集合最后一个元素,第N次计算的时候第二个参数的值 = 第N-1次的结果
  86. println("-"*100)
  87. val r1 = list.reduceRight((curr,agg)=>{
  88. println(s"agg=${agg} curr=${curr}")
  89. agg-curr
  90. })
  91. println(r1)
  92. //fold(初始值)(func: (集合元素类型,集合元素类型)=>集合元素类型): 从左向右计算
  93. //fold是对集合中所有元素进行聚合
  94. //fold函数第一个参数第一次计算的时候初始值 = 指定默认值,第N次计算的时候第一个参数的值 = 第N-1次的结果
  95. println("*"*100)
  96. list.fold(100)((agg,curr)=>{
  97. println(s"agg=${agg} curr=${curr}")
  98. agg+curr
  99. })
  100. println("+"*100)
  101. //foldRight(初始值)(func: (集合元素类型,集合元素类型)=>集合元素类型): 从右向左计算
  102. // foldRight是对集合中所有元素进行聚合
  103. //foldRight函数第二个参数第一次计算的时候初始值 = 指定默认值,第N次计算的时候第二个参数的值 = 第N-1次的结果
  104. list.foldRight(200)((curr,agg)=>{
  105. println(s"agg=${agg} curr=${curr}")
  106. agg+curr
  107. })
  108. }
  109. }