一、数组
scala中数组的概念是和Java类似,可以用数组来存放一组数据。scala中,有两种数组,一种是定 长数组,另一种是变长数组
1、定长数组
定长数组指的是数组的长度是不允许改变的
语法
// 通过指定长度定义数组
val/var 变量名 = new Array元素类型 (长度)
// 用元素直接初始化数组
val/var 变量名 = Array(元素1, 元素2, 元素3...)
- 在scala中,数组的泛型使用 [] 来指定
- 使用 () 来获取元素
示例一
-
定义一个长度为100的整型数组
-
设置第1个元素为110
-
打印第1个元素
scala> val arr1=new Array[Int](100) arr1: Array[Int] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) scala> arr1(0)=110 scala> println(arr1(0))
示例二
-
定义一个包含以下元素的数组
"java", "scala", "python"
-
获取数组长度
scala> val arr2= Array("java","scala","python") arr2: Array[String] = Array(java, scala, python) scala> arr2.length res2: Int = 3
2、变长数组
变长数组指的是数组的长度是可变的,可以往数组中添加、删除元素
-
定义变长数组
-
语法
-
创建空的ArrayBuffer变长数组,语法结构:
val/var a = ArrayBuffer[元素类型]()
-
创建带有初始元素的ArrayBuffer
val/var a = ArrayBuffer(元素1,元素2,元素3....)
创建变长数组,需要提前导入ArrayBuffer类 import scala.collection.mutable.ArrayBuffer
-
-
示例一
定义一个长度为0的整型变长数组
val a = ArrayBuffer[Int]()
-
示例二
定义一个包含以"hadoop", “storm”, “spark” 元素的变长数组
scala> val a = ArrayBuffer("hadoop", "storm", "spark") a: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(hadoop, storm, spark)
-
3、添加/修改/删除元素
-
使用 += 添加元素
-
使用 -= 删除元素
-
使用 ++= 追加一个数组到变长数组
-
示例
-
定义一个变长数组,包含以下元素: “hadoop”, “spark”, “flink”
-
往该变长数组添加一个"flume"元素
-
从该变长数组删除"hadoop"元素
-
再将一个数组,该数组包含"hive", "sqoop"追加到变长数组中
scala> import scala.collection.mutable.ArrayBuffer import scala.collection.mutable.ArrayBuffer scala> val a=ArrayBuffer("hadoop","spark","flink") a: scala.collection.mutable.ArrayBuffer[String] = ArrayBuffer(hadoop, spark, flink) scala> a+="flume" res0: a.type = ArrayBuffer(hadoop, spark, flink, flume) scala> a-="hadoop" res1: a.type = ArrayBuffer(spark, flink, flume) scala> a++=ArrayBuffer("hive","sqoop") res2: a.type = ArrayBuffer(spark, flink, flume, hive, sqoop)
-
4、遍历数组
可以使用以下两种方式来遍历数组:
-
使用 for表达式 直接遍历数组中的元素
-
使用 索引 遍历数组中的元素
-
示例一
-
定义一个数组,包含以下元素1,2,3,4,5
-
使用for表达式直接遍历,并打印数组的元素
val a =Array(1,2,3,4,5) for (i <- a){ println(i) }
-
-
示例二
-
定义一个数组,包含以下元素1,2,3,4,5
-
使用for表达式基于索引下标遍历,并打印数组的元素
val a =Array(1,2,3,4,5) for(i <- 0 to a.length-1){ println(a(i)) }
或者
for(i <- 0 until a.length) println(a(i))
**0 until n——生成一系列的数字,包含0,不包含n **
0 to n ——包含0,也包含n
-
5、数组常用算法
-
求和
-
数组中的 sum 方法可以将所有的元素进行累加,然后得到结果
-
示例
-
定义一个数组,包含以下几个元素(1,2,3,4)
-
请计算该数组的和
scala> val a=Array(1,2,3,4) a: Array[Int] = Array(1, 2, 3, 4) scala> a.sum res8: Int = 10
-
-
-
最大值
-
数组中的 max 方法,可以获取到数组中的最大的那个元素值
-
示例
-
定义一个数组,包含以下几个元素(4,1,2,4,10)
-
获取数组的最大值
scala> val a=Array(4,1,2,4,10) a: Array[Int] = Array(4, 1, 2, 4, 10) scala> a.max res9: Int = 10
-
-
-
最小值
-
数组的 min 方法,可以获取到数组中最小的那个元素值
-
示例
-
定义一个数组,包含以下几个元素(4,1,2,4,10)
-
获取数组的最小值
scala> val a=Array(4,1,2,4,10) a: Array[Int] = Array(4, 1, 2, 4, 10) scala> a.min res10: Int = 1
-
-
-
排序
-
数组的 sorted 方法,可以对数组进行升序排序。而 reverse 方法,可以将数组进行反转,从而
实现降序排序。
-
示例
-
定义一个数组,包含以下几个元素(4,1,2,4,10)
-
对数组进行升序排序、降序排序
scala> val a=Array(4,1,2,4,10) a: Array[Int] = Array(4, 1, 2, 4, 10) scala> a.sorted res11: Array[Int] = Array(1, 2, 4, 4, 10) scala> a.sorted.reverse res12: Array[Int] = Array(10, 4, 4, 2, 1)
-
-
二、元祖
元组可以用来包含一组不同类型的值。例如:姓名,年龄,性别,出生年月。元组的元素是不可变的。
1、定义元组
-
语法
使用括号来定义元组
val/var 元组 = (元素1, 元素2, 元素3....)
使用箭头来定义元素(元组只有两个元素)
val/var 元组 = 元素1->元素2
-
示例:使用括号
scala> val a = (1, "张三", 20, "北京市") a: (Int, String, Int, String) = (1,张三,20,北京市)
-
示例:使用箭头(元组只有两个元素)
scala> val a = "age" ->20 a: (String, Int) = (age,20)
2、访问元组
-
使用_1、_2、_3…来访问元组中的元素,_1表示访问第一个元素,依次类推
-
示例:定义一个元组(1, “张三”, 20, “北京市” ),分别获取第一个元素 和第二个元素
//定义元祖 scala> val a = (1, "张三", 20, "北京市") a: (Int, String, Int, String) = (1,张三,20,北京市) //获取第一个元素 scala> a._1 res13: Int = 1 //获取第二个元素 scala> a._2 res14: String = 张三 //修改第一个元素,不能被修改 scala> a._1=5 <console>:13: error: reassignment to val a._1=5
三、列表
List是scala中最重要的、也是最常用的数据结构。List具备以下性质:
- 可以保存重复的值
- 有先后顺序
在scala中,也有两种列表,一种是不可变列表、另一种是可变列表
1、不可变列表
不可变列表就是列表的元素、长度都是不可变的。
-
语法
使用 List(元素1, 元素2, 元素3, …) 来创建一个不可变列表,语法格式:
val/var 变量名 = List(元素1, 元素2, 元素3...)
-
使用 Nil 创建一个不可变的空列表
val/var 变量名 = Nil
-
使用 :: 方法创建一个不可变列表
val/var 变量名 = 元素1 :: 元素2 :: Nil
-
示例一
创建一个不可变列表,存放以下几个元素(1,2,3,4)
scala> val list=List(1,2,3,4) list: List[Int] = List(1, 2, 3, 4)
-
示例二
使用Nil创建一个不可变的空列表
scala> val a=Nil a: scala.collection.immutable.Nil.type = List()
-
示例三
使用 :: 方法创建列表,包含-2、-1两个元素
scala> val list = -1 :: -2 :: Nil list: List[Int] = List(-1, -2)
2、可变列表
可变列表就是列表的元素、长度都是可变的。
要使用可变列表,先要导入 import scala.collection.mutable.ListBuffer
可变集合都在 mutable 包中
不可变集合都在 immutable 包中(默认导入)
-
初始化列表
-
语法
使用ListBuffer[ 类型 ] ()创建空的可变列表,语法结构:
val/var 变量名 = ListBuffer[Int]()=
使用ListBuffer(元素1, 元素2, 元素3…)创建可变列表,语法结构:
val/var 变量名 = ListBuffer(元素1,元素2,元素3...)
-
示例一
创建空的可变列表
val a=ListBuffer[Int]()
-
示例二
创建一个可变列表,包含以下元素:1,2,3,4
scala> val a=ListBuffer(1,2,3,4) a: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3, 4)
-
3、列表操作
-
获取元素(使用括号访问 (索引值) )
-
添加元素( += )
-
追加一个列表( ++= )
-
更改元素( 使用括号获取元素,然后进行赋值 )
-
删除元素( -= )
-
转换为List( toList )
-
转换为Array( toArray )
-
示例一
-
定义一个可变列表包含以下元素:1,2,3
-
获取第一个元素
-
添加一个新的元素:4
-
追加一个列表,该列表包含以下元素:5,6,7
-
删除元素7
-
将可变列表转换为不可变列表
-
将可变列表转换为数组
//定义可变列表 scala> val a = ListBuffer(1,2,3) a: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 2, 3) //获取第一个元素 scala> a(0) res0: Int = 1 //添加元素 scala> a+=4 res1: a.type = ListBuffer(1, 2, 3, 4) //追加列表 scala> a++=ListBuffer(5,6,7) res2: a.type = ListBuffer(1, 2, 3, 4, 5, 6, 7) //删除元素7 scala> a -=7 res3: a.type = ListBuffer(1, 2, 3, 4, 5, 6) //可变列表转不可变列表 scala> a.toList res4: List[Int] = List(1, 2, 3, 4, 5, 6) //列表转数组 scala> a.toArray res5: Array[Int] = Array(1, 2, 3, 4, 5, 6)
-
4、列表的常用操作
-
判断列表是否为空( isEmpty )
-
示例1:使用length方法来获取列表长度
scala> val a =List(1,2,3,4) a: List[Int] = List(1, 2, 3, 4) scala> a.length res6: Int = 4
-
-
拼接两个列表( ++ )
-
示例2:使用++方法来拼接连接列表来形成一个新的列表
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> val b = List(4,5,6) b: List[Int] = List(4, 5, 6) scala> val c = a ++ b c: List[Int] = List(1, 2, 3, 4, 5, 6)
-
-
获取列表的首个元素( head )和剩余部分( tail )
-
示例3:获取列表的首个元素和剩余部分
-
使用head方法,获取列表的首个元素
-
使用tail方法,获取除第一个元素以外的元素,它也是一个列表
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> a.head res7: Int = 1 scala> a.tail res8: List[Int] = List(2, 3)
-
-
-
反转列表( reverse )
-
示例4:使用reverse方法将列表的元素反转
scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> a.reverse res9: List[Int] = List(3, 2, 1)
-
-
获取前缀( take )、获取后缀( drop )
-
示例5:获取列表的前缀、后缀以
使用take方法获取前n个元素
scala> val a = List(1,2,3,4,5) a: List[Int] = List(1, 2, 3, 4, 5) // 获取列表a的前3个元素 scala> a.take(3) res10: List[Int] = List(1, 2, 3)
使用drop方法获取除了前3个元素以外的元素
scala> val a = List(1,2,3,4,5) a: List[Int] = List(1, 2, 3, 4, 5) scala> a.drop(3) res11: List[Int] = List(4, 5)
-
-
扁平化( flatten)
-
示例6:扁平化操作,扁平化表示将列表中的列表中的所有元素放到一个列表中。
scala> val a = List(List(1,2), List(3), List(4,5)) a: List[List[Int]] = List(List(1, 2), List(3), List(4, 5)) scala> a.flatten res11: List[Int] = List(1, 2, 3, 4, 5)
-
-
拉链( zip )和拉开( unzip )
-
示例7:拉链与拉开
使用zip将两个列表,组合成一个元素为元组的列表
scala> val a = List("张三", "李四", "王五") a: List[String] = List(张三, 李四, 王五) scala> val b = List(18,19,20) b: List[Int] = List(18, 19, 20) scala> a.zip(b) res12: List[(String, Int)] = List((张三,18), (李四,19), (王五,20))
使用unzip将一个包含元组的列表,解开成两个列表的元组
scala> res12.unzip res13: (List[String], List[Int]) = (List(张三, 李四, 王五),List(18, 19, 20))
-
-
转换字符串( toString )
-
示例8:toString返回列表的标准字符串表现形式
scala> val a = List(1,2,3,4) a: List[Int] = List(1, 2, 3, 4) scala> println(a.toString) List(1, 2, 3, 4)
-
-
生成字符串( mkString )
-
示例9:mkString表示使用什么样的分隔符来展示列表
scala> a.mkString(":") res16: String = 1:2:3:4
可以调用mkString的另一种重载方式,加上前缀和后缀
scala> a.mkString("[", ":", "]") res17: String = [1:2:3:4]
-
-
并集( union )
-
union表示对两个列表取并集,不去重
scala> val a1 = List(1,2,3,4) a1: List[Int] = List(1, 2, 3, 4) scala> val a2 = List(2,3,5) a2: List[Int] = List(2, 3, 5) scala> a1.union(a2) res18: List[Int] = List(1, 2, 3, 4, 2, 3, 5)
-
可以调用distinct去重
scala> a1.union(a2).distinct res19: List[Int] = List(1, 2, 3, 4, 5)
-
-
交集( intersect )
-
intersect表示对两个列表取交集,不去重
scala> val a1 = List(1,2,3,4) a1: List[Int] = List(1, 2, 3, 4) scala> val a2 = List(2,3,5) a2: List[Int] = List(2, 3, 5) scala> a1.intersect(a2) res20: List[Int] = List(2, 3)
-
-
差集( diff )
-
diff表示对两个列表取差集,例如: a1.diff(a2),表示将a1中不包含a2中的元素
scala> val a1 = List(1,2,3,4) a1: List[Int] = List(1, 2, 3, 4) scala> val a2 = List(2,3,5) a2: List[Int] = List(2, 3, 5) scala> a1.diff(a2) res21: List[Int] = List(1, 4)
-
四、Set
Set(集)是代表没有重复元素的集合。Set具备以下性质:
-
**元素不重复 **
-
**不保证插入顺序 **
scala中的集也分为两种,一种是不可变集,另一种是可变集。
1、不可变集
-
语法
创建一个空的不可变集,语法格式:
val/var 变量名 = Set[类型]()
给定元素来创建一个不可变集,语法格式:
val/var 变量名 = Set[类型](元素1, 元素2, 元素3...)
-
基本操作
- 获取集的大小( size )
- 遍历集合( 和遍历数组一致 )
- 添加一个元素,生成一个Set( + )
- 拼接两个集,生成一个Set( ++ )
- 拼接集和列表,生成一个Set( ++ )
-
案例
- 创建一个集,包含以下元素:1,1,2,3,4,5
- 获取集的大小
- 遍历集合,打印每个元素
- 删除元素1
- 拼接另一个集(6, 7, 8)
- 拼接一个列表(6,7,8, 9)
scala> val a = Set(1,1,2,3,4,5)
a: scala.collection.immutable.Set[Int] = Set(5, 1, 2, 3, 4)
//获取集的大小
scala> a.size
res22: Int = 5
//遍历集合
scala> for (i <- a) println(i)
5
1
2
3
4
scala> a - 1
res24: scala.collection.immutable.Set[Int] = Set(5, 2, 3, 4)
scala> a ++ Set(6,7,8)
res25: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 2, 7, 3, 8, 4)
scala> a ++ List(6,7,8,9)
res26: scala.collection.immutable.Set[Int] = Set(5, 1, 6, 9, 2, 7, 3, 8, 4)
2、可变集
要使用可变集,必须要手动导入: import scala.collection.mutable.Set
-
示例
- 定义一个可变集,包含以下元素: 1,2,3, 4
- 添加元素5到可变集中
- 从可变集中移除元素1
scala> val a = Set(1,2,3,4) a: scala.collection.mutable.Set[Int] = Set(1, 2, 3, 4) scala> a + 5 res27: scala.collection.mutable.Set[Int] = Set(1, 5, 2, 3, 4) scala> a - 1 res28: scala.collection.mutable.Set[Int] = Set(2, 3, 4)
五、映射
Map可以称之为映射。它是由键值对组成的集合。在scala中,Map也分为不可变Map和可变 Map
1、不可变Map
-
定义语法
val/var map = Map(键->值, 键->值, 键->值...) // 推荐,可读性更好 val/var map = Map((键, 值), (键, 值), (键, 值), (键, 值)...)
-
示例
-
定义一个映射,包含以下学生姓名和年龄数据
“zhangsan”, 30
“lisi”, 40
-
获取zhangsan的年龄
scala> val map=Map("zhangsan"->30,"lisi"->40) map: scala.collection.immutable.Map[String,Int] = Map(zhangsan -> 30, lisi -> 40) scala> map("zhangsan") res29: Int = 30
-
2、可变Map
可变Map需要手动导入 import scala.collection.mutable.Map
定义语法与不可变Map一致。
-
示例
-
定义一个映射,包含以下学生姓名和年龄数据
“zhangsan”, 30
“lisi”, 40
-
修改zhangsan的年龄为20
scala> import scala.collection.mutable.Map import scala.collection.mutable.Map scala> val map=Map("zhangsan"->30,"lisi"->40) map: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30) scala> map("zhangsan")=20
-
3、Map基本操作
-
获取值( map(key) )
-
获取所有key( map.keys )
-
获取所有value( map.values )
-
遍历map集合
-
getOrElse
-
增加key,value对
-
删除key
-
示例
-
定义一个映射,包含以下学生姓名和年龄数据
“zhangsan”, 30
“lisi”, 40
-
获取zhagnsan的年龄
-
获取所有的学生姓名
-
获取所有的学生年龄
-
打印所有的学生姓名和年龄
-
获取wangwu的年龄,如果wangwu不存在,则返回-1
-
新增一个学生:wangwu, 35
-
将lisi从可变映射中移除
scala> val map = Map("zhangsan"->30, "lisi"->40) map: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30) // 获取zhagnsan的年龄 scala> map("zhangsan") res10: Int = 30 // 获取所有的学生姓名 scala> map.keys res13: Iterable[String] = Set(lisi, zhangsan) // 获取所有的学生年龄 scala> map.values res14: Iterable[Int] = HashMap(40, 30) // 打印所有的学生姓名和年龄 scala> for((x,y) <- map) println(s"$x $y") lisi 40 zhangsan 30 // 获取wangwu的年龄,如果wangwu不存在,则返回-1 scala> map.getOrElse("wangwu", -1) res17: Int = -1 // 新增一个学生:wangwu, 35 scala> map + ("wangwu"->35) res22: scala.collection.mutable.Map[String,Int] = Map(lisi -> 40, zhangsan -> 30, wangw u -> 35) // 将lisi从可变映射中移除 scala> map - "lisi" res23: scala.collection.mutable.Map[String,Int] = Map(zhangsan -> 30)
-
六、函数式编程
1、遍历( foreach )
之前,学习过了使用for表达式来遍历集合。我们接下来将学习scala的函数式编程,使用 foreach 方法来进行遍历、迭代。它可以让代码更加简洁。
方法
foreach(f: (A) ⇒ Unit): Unit
说明
foreach | API | 说明 |
---|---|---|
参数 | f: (A) ⇒ Unit | 接收一个函数对象 函数的输入参数为集合的元素,返回值为空 |
返回值 | Unit | 空 |
示例
有一个列表,包含以下元素1,2,3,4,请使用foreach方法遍历打印每个元素
scala> val a = List(1,2,3,4)
a: List[Int] = List(1, 2, 3, 4)
scala> a.foreach((x:Int)=>println(x))
使用类型推断简化函数定义
上述案例函数定义有点啰嗦,我们有更简洁的写法。因为使用foreach去迭代列表,而列表中的每元素类型是确定的
- scala可以自动来推断出来集合中每个元素参数的类型
- 创建函数时,可以省略其参数列表的类型
- 示例
- 有一个列表,包含以下元素1,2,3,4,请使用foreach方法遍历打印每个元素
- 使用类型推断简化函数定义
// 省略参数类型
scala> a.foreach(x=>println(x))
使用下划线来简化函数定义
当函数参数,只在函数体中出现一次,而且函数体没有嵌套调用时,可以使用下划线来简化函数定义
-
示例
-
有一个列表,包含以下元素1,2,3,4,请使用foreach方法遍历打印每个元素
-
使用下划线简化函数定义
scala> val a = List(1,2,3,4) a: List[Int] = List(1, 2, 3, 4) scala> a.foreach(println(_))
-
-
如果方法参数是函数,如果出现了下划线,scala编译器会自动将代码封装到一个函数中
-
参数列表也是由scala编译器自动处理
2、映射( map )
map方法接收一个函数,将这个函数应用到每一个元素,返回一个新的列表
方法
def map[B](f: (A) ⇒ B): TraversableOnce[B]
方法解析
map方法 | API | 说明 |
---|---|---|
泛型 | [B] | 指定map方法最终返回的集合泛型 |
参数 | f: (A) ⇒ B | 传入一个函数对象 该函数接收一个类型A(要转换的列表元素),返回值为类型B |
返回值 | TraversableOnce[B] | B类型的集合 |
-
案例一
-
创建一个列表,包含元素1,2,3,4
-
对List中的每一个元素加1
scala> a.map(x=>x+1) res56: List[Int] = List(2, 3, 4, 5)
-
-
案例二
-
创建一个列表,包含元素1,2,3,4
-
使用下划线来定义函数,对List中的每一个元素加1
scala> val a = List(1,2,3,4) a: List[Int] = List(1, 2, 3, 4) scala> a.map(_+1) res57: List[Int] = List(2, 3, 4, 5)
-
3、映射扁平化( flatmap )
可以把flatMap,理解为先map,然后再flatten
-
map是将列表中的元素转换为一个List
-
flatten再将整个列表进行扁平化
-
方法
def flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): TraversableOnce[B]
-
方法解析
flatmap方法 API 说明 泛型 [B] 最终要转换的集合元素类型 参数 f: (A) ⇒ GenTraversableOnce[B] 传入一个函数对象
函数的参数是集合的元素
函数的返回值是一个集合返回值 TraversableOnce[B] B类型的集合 -
案例
- 有一个包含了若干个文本行的列表:“hadoop hive spark flink flume”, “kudu hbase sqoop storm”
-
获取到文本行中的每一个单词,并将每一个单词都放到列表中
-
第一种方式
- 使用map将文本行拆分成数组
- 再对数组进行扁平化
scala> val a = List("hadoop hive spark flink flume", "kudu hbase sqoop storm") a: List[String] = List(hadoop hive spark flink flume, kudu hbase sqoop storm) scala> a.map(x=>x.split(" ")) res58: List[Array[String]] = List(Array(hadoop, hive, spark, flink, flume), Array(kudu, hbase, sqoop, storm)) scala> a.map(x=>x.split(" ")).flatten res59: List[String] = List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)
-
第二种方式直接使用flatmap
scala> a.flatMap(_.split(" ")) res60: List[String] = List(hadoop, hive, spark, flink, flume, kudu, hbase, sqoop, storm)
-
4、过滤( filter )
过滤符合一定条件的元素
方法
def filter(p: (A) ⇒ Boolean): TraversableOnce[A]
方法解析
filter方法 | API | 说明 |
---|---|---|
参数 | p: (A) ⇒ Boolean | 传入一个函数对象 接收一个集合类型的参数 返回布尔类型,满足条件返回true, 不满足返回false |
返回值 | TraversableOnce[A] | 列表 |
-
案例
-
有一个数字列表,元素为:1,2,3,4,5,6,7,8,9
-
请过滤出所有的偶数
scala> List(1,2,3,4,5,6,7,8,9).filter(_ % 2 == 0) res61: List[Int] = List(2, 4, 6, 8)
-
5、排序( sorted 、 sortBy 、 sortWith )
在scala集合中,可以使用以下几种方式来进行排序
-
sorted默认排序
-
示例
-
定义一个列表,包含以下元素: 3, 1, 2, 9, 7
-
对列表进行升序排序
scala> List(3,1,2,9,7).sorted res62: List[Int] = List(1, 2, 3, 7, 9)
-
-
-
sortBy指定字段排序
-
根据传入的函数转换后,再进行排序
-
方法
def sortBy[B](f: (A) ⇒ B): List[A]
sortBy方法 API 说明 泛型 [B] 按照什么类型来进行排序 参数 f: (A) ⇒ B 传入函数对象
接收一个集合类型的元素参数
返回B类型的元素进行排序返回值 List[A] 返回排序后的列表
-
-
示例
-
有一个列表,分别包含几下文本行:“01 hadoop”, “02 flume”, “03 hive”, “04 spark”
-
请按照单词字母进行排序
scala> val a = List("01 hadoop", "02 flume", "03 hive", "04 spark") a: List[String] = List(01 hadoop, 02 flume, 03 hive, 04 spark) scala> a.sortBy(_.split(" ")(1)) res63: List[String] = List(02 flume, 01 hadoop, 03 hive, 04 spark)
-
-
sortWith自定义排序
-
自定义排序,根据一个函数来进行自定义排序
-
方法
def sortWith(lt: (A, A) ⇒ Boolean): List[A]
-
方法解析
sortWith方法 API 说明 参数 lt: (A, A) ⇒ Boolean 传入一个比较大小的函数对象
接收两个集合类型的元素参数
返回两个元素大小,小于返回true,大于返回false返回值 List[A] 返回排序后的列表 -
示例
-
有一个列表,包含以下元素:2,3,1,6,4,5
-
使用sortBy对列表进行降序排序
scala> val a = List(2,3,1,6,4,5) a: List[Int] = List(2, 3, 1, 6, 4, 5) scala> a.sortWith((x,y)=>if(x<y)true else false) res0: List[Int] = List(1, 2, 3, 4, 5, 6) scala> res0.reverse res1: List[Int] = List(6, 5, 4, 3, 2, 1)
使用下划线简写上述案例
scala> val a = List(2,3,1,6,4,5) a: List[Int] = List(2, 3, 1, 6, 4, 5) scala> a.sortWith(_ < _).reverse res3: List[Int] = List(6, 5, 4, 3, 2, 1)
-
-
6、分组( groupBy )
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为这个分组字段对应的一组数据 |
-
示例
-
有一个列表,包含了学生的姓名和性别:
"张三", "男" "李四", "女" "王五", "男"
-
请按照性别进行分组,统计不同性别的学生人数
步骤
- 定义一个元组列表来保存学生姓名和性别
- 按照性别进行分组
- 将分组后的Map转换为列表:List((“男” -> 2), (“女” -> 1))
scala> val a =List(("张三"->"男"),("李四"->"女"),("王五"->"男")) a: List[(String, String)] = List((张三,男), (李四,女), (王五,男)) scala> a.groupBy(_._2) res4: scala.collection.immutable.Map[String,List[(String, String)]] = Map(男 -> List((张三,男), (王五,男)), 女 -> List((李四,女))) scala> res4.map(x=>x._1->x._2.size) res5: 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 | 列表最终聚合为一个元素 |
reduce执行流程分析
- reduce和reduceLeft效果一致,表示从左到右计算
- reduceRight表示从右到左计算
案例:
-
定义一个列表,包含以下元素:1,2,3,4,5,6,7,8,9,10
-
使用reduce计算所有元素的和
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) res6: Int = 55 //或者使用下划线 // 第一个下划线表示第一个参数,就是历史的聚合数据结果 // 第二个下划线表示第二个参数,就是当前要聚合的数据元素 scala> a.reduce(_ + _) res7: Int = 55 // 与reduce一样,从左往右计算 scala> a.reduceLeft(_ + _) res8: Int = 55 // 从右往左聚合计算 scala> a.reduceRight(_+_) res9: Int = 55
8、折叠( fold )
fold与reduce很像,但是多了一个指定初始值参数
方法
def fold[A1 >: A](z: A1)(op: (A1, A1) ⇒ A1): A1
方法解析
fold方法 | API | 说明 |
---|---|---|
泛型 | [A1 >: A] | (下界)A1必须是集合元素类型的子类 |
参数1 | z: A1 | 初始值 |
参数2 | op: (A1, A1) ⇒ A1 | 传入函数对象,用来不断进行折叠操作 第一个A1类型参数为:当前折叠后的变量 第二个A1类型参数为:当前要进行折叠的元素 |
返回值 | A1 | 列表最终折叠为一个元素 |
- fold和foldLet效果一致,表示从左往右计算
- foldRight表示从右往左计算
案例:
-
定义一个列表,包含以下元素:1,2,3,4,5,6,7,8,9,10
-
使用fold方法计算所有元素的和
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.fold(0)(_+_) res10: Int = 55