Scala 同时支持不可变集合 和可变集合 ,因为不可变集合可以安全的并发访问 ,所以它也是默认使用的集合类库。在Scala 中,对于几乎所有的集合类,都提供了可变和不可变两个版本,具体如下:
不可变集合:集合内的元素、长度一旦初始化完成就不可再进行更改,任何对集合的改变都将生成一个新的集合。不可变集合都在 scala.collection.immutable 这个包下,使用时无需手动导包。
可变集合:指的是这个集合本身可以动态改变,且可变集合提供了改变集合内元素的方法。可变集合都在scala.collection.mutable 这个包下,使用时需要手动导包。
4.1. 结构树
蓝色为特质(接口),黑色为实现类

4.2. Traversable
4.2.1. 语法格式
创建空的Traversale
val t1 = Traversable.empty[Int]
val t2 = Traversable[Int]()
val t3 = Nil
创建带元素的Traversable对象
val t4 = List(1,2,3).toTraversable List为默认实现类
val t5=Array(1,2,3).toTraversable
val t6 = Set(1,2,3).toTraversable
通过Traversable伴生对象apply方式实现
val t7 = Traversable(1,2,3)
4.2.2. 转置集合transpose
val t8 = Traversable(Traversable(1,2,3),Traversable(4,5,6),Traversable(7,8,9))
val result1 =t8.transpose
println(result1)
List(List(1, 4, 7), List(2, 5, 8), List(3, 6, 9))
4.2.3. 拼接集合 Traversable.concat(x,x,x)
已知有三个 Traversable 集合,分别存储 (11, 22, 33), (44, 55), (66, 77, 88, 99) 元素
通过 concat 方法拼接上述三个集合
将拼接后的结果打印到控制台
val t9 = List(11,22,33).toTraversable
val t10 = List(44,55).toTraversable
val t11 = Traversable(66,77,88,99)
val result2 = Traversable.concat(t9,t10,t11)
println(result2)
List(11, 22, 33, 44, 55, 66, 77, 88, 99)拼接成一个集合
4.2.4. 计算阶乘
val t12 = Traversable(1,2,3,4,5)
val result3 = t12.scan(1)(_*_)
scan(1)代表起始值为1
完整scan(1)((x:Int,y:Int)=>x*y)
println(result3)
List(1, 1, 2, 6, 24, 120)
1*1 1*2 2*3 6*4 24*5
从左往右
val result4 = t12.scanLeft(1)(_*_)
从右往左
val result5 = t12.scanRight(1)(_*_)
4.2.5. 获取元素
head :获取集合的第一个元素,如果元素不存在,则抛出 NoSuchElementException 异常
last :获取集合的最后一个元素,如果元素不存在,则抛出 NoSuchElementException 异常
headOption :获取集合的第一个元素,返回值类型是 Option
lastOption :获取集合的最后一个元素,返回值类型是 Option
find :查找集合中第一个满足指定条件的元素
slice :截取集合中的一部分元素(左闭右开)
需求:
定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6
分别通过 head、last、headOption、lastOption 获取集合中的首尾元素
通过 find 方法获取集合中第一个偶数
通过 slice 方法获取 3, 4, 5 并将它们放到一个新的 Traversable 集合
val t13 = Traversable(1,2,3,4,5,6)
println(t13.head,t13.last,t13.headOption.getOrElse(0),t13.lastOption.getOrElse(0))
getOrElse(0)如果不存在就返回0
(1,6,Some(1),Some(6))
val result6= t13.find(_ % 2 == 0)
(x)=>{x%2==0}
println(result6)
Some(2)
val result7=t13.slice(2,5)
println(result7)
List(3, 4, 5)
4.2.6. 判断元素
def forall(p: (A) => Boolean): Boolean
如果集合中所有元素都满足指定的条件则返回 true,否则返回 false
def exists(p: (A) => Boolean): Boolean
只要集合中任意一个元素满足指定的条件就返回 true,否则返回 false
需求:
定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6
通过 forall 方法判断集合中的元素是否都是偶数
通过 exists 方法判断集合中的元素是否有偶数
val t14 = Traversable(1,2,3,4,5,6)
val result8 = t14.forall(_%2==0)
val result9 = t14.exists(_%2==0)
println(result8,result9)
(false,true)
4.2.7. 聚合操作
count :统计集合中满足条件的元素个数
sum :获取集合中所有的元素和
product :获取集合中所有的元素乘积
max :获取集合中所有元素的最大值
min :获取集合中所有元素的最小值
需求:
定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6
通过 count 方法统计集合中所有奇数的个数
通过 sum 方法获取集合中所有元素的和
通过 product 方法获取集合中所有元素的乘积
通过 max 方法获取集合中所有元素的最大值
通过 min 方法获取集合中所有元素的最小值
val t15 = Traversable(1,2,3,4,5,6)
val result10 = t15.count(_%2==1)
val result11 = t15.sum
val result12 = t15.product
val result13 = t15.max
val result14 = t15.min
println(result10,result11,result12,result13,result14)
(3,21,720,6,1)
4.2.8. 类型转换
toXxx() 方法(toList, toSet, toArray, toSeq 等)。
需求:
定义一个 Traversable 集合,包含 1, 2, 3, 4, 5, 6
将集合分别转成数组、列表、集这三种形式,并打印结果
val t16 = Traversable(1,2,3,4,5,6)
val resultArray = t16.toArray
val resultList = t16.toList
val resultSet = t16.toSet
println(resultArray,resultList,resultSet)
([I@57855c9a,List(1, 2, 3, 4, 5, 6),Set(5, 1, 6, 2, 3, 4))
4.2.9. 填充元素
fill :快速生成指定数量的元素,并放入集合中
iterate :根据指定的条件,生成指定数量的元素,并放入集合中
range :生成某个区间内指定间隔的元素,并放入集合中
需求:
通过 fill 方法,生成一个 Traversable 集合,该集合包含 5 个元素,都是"abc"
通过 fill 方法,生成一个 Traversable 集合,该集合包含 3 个随机数
通过 fill 方法,生成一个 Traversable 集合,该集合包含 5 个元素,都是 List("abc", "abc") 集合
通过 iterate 方法,生成一个 Traversable 集合,该集合包含 5 个元素,分别为:1, 10, 100, 1000, 10000
通过 range 方法,获取从数字 1 开始到数字 21 结束,间隔为 5 的所有数据
println(Traversable.fill(5)("abc"))
List(abc, abc, abc, abc, abc)
println(Traversable.fill(3)(Random.nextInt(100)))一百以内的随机整数
List(62, 71, 37)
println(Traversable.fill(5,2)("abc"))
5 表示生成的集合中有 5 个集合元素,2 表示每个集合元素的长度为 2
List(List(abc, abc), List(abc, abc), List(abc, abc), List(abc, abc), List(abc, abc))
println(Traversable.iterate(1,5)(x=>x*10))
List(1, 10, 100, 1000, 10000)
println(Traversable.range(1,21,5))左闭右开
List(1, 6, 11, 16)
4.3. Iterable
4.3.1. 遍历
Traversable 提供了两种遍历数据的方式:
通过 iterator() 方法实现,迭代访问元素。这种方式属于主动迭代,可以通过 hasNext() 检查是否还有元素,且可以主动的调用 next() 方法获取元素。即:我们可以自主控制迭代过程。
通过 foreach() 方法实现,遍历访问元素。这种方式属于被动迭代,只需要提供一个函数,并不能控制遍历的过程。即:迭代过程是由集合本身控制的。
需求:
定义一个 Traversable 集合,包含 1, 2, 3, 4, 5
通过 iterator() 方法遍历上述列表
通过 foreach() 方法遍历上述列表
val t17 = Traversable(1,2,3,4,5,6)
val iterator: Iterator[Int] = t17.toIterator
while(iterator.hasNext){
print(iterator.next())
}
123456
println()
val result15 = t17.foreach(print)
foreach(x=>println(x))
123456
println()
4.3.2. 分组遍历
def grouped(size: Int): Iterator[Ierable[A]]
需求:
定义一个 Iterable 集合,存储 1~13 之间的所有整数
通过 grouped() 方法,对 Iterator 集合按照 5 个元素为一组的形式进行分组,遍历并打印结果
val t18= (1 to 13).toIterable
val result16 = t18.grouped(5)每组5个
result16.foreach(print(_))
Vector(1, 2, 3, 4, 5)Vector(6, 7, 8, 9, 10)Vector(11, 12, 13)
println()
4.3.3. 按索引生成元组
需求:
定义一个 Iterable 集合,存储 "A", "B", "C", "D", "E"
通过 zipWithIndex() 方法按照 字符串 -> 索引 生成新的集合
将上一步结果通过 map() 方法再按照 索引 -> 字符串 生成新的集合
val t19 = ('A' to 'E').toIterable
val result17 = t19.zipWithIndex
println(result17)
Vector((A,0), (B,1), (C,2), (D,3), (E,4))
val result18 = result17.map(x=>x._1->x._2)
println(result18)
Vector((A,0), (B,1), (C,2), (D,3), (E,4))
4.3.4. 判断集合是否相同
需求:
定义 Iterable 集合 iter1,包含 "A", "B", "C"
通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "B", "C") 是否相同
通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "C", "B") 是否相同
定义 Iterable 集合 iter2,包含 "A", "B", "C", "D"
通过 sameElements() 方法,判断集合 iter1 和 iter2 是否相同
思考:HashSet(1, 5, 2, 3, 4) 和 TreeSet(2, 1, 4, 3, 5) 是否相同?
val t20 = Iterable("A" ,"B", "C")
通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "B", "C") 是否相同
println(t20.sameElements(Iterable("A", "B", "C"))) true
通过 sameElements() 方法,判断集合 iter1 和 Iterable("A", "B", "C") 是否相同
println(t20.sameElements(Iterable("A", "C", "B"))) false
定义 Iterable 集合 iter2,包含 "A", "B", "C", "D"
val iter2 = Iterable("A", "B", "C", "D")
通过 sameElements() 方法,判断集合 iter1 和 iter2 是否相同
println(t20.sameElements(iter2)) false
思考:HashSet(1, 5, 2, 3, 4) 和 TreeSet(2, 1, 4, 3, 5) 是否相同?
println(mutable.HashSet(1, 5, 2, 3, 4).sameElements(mutable.TreeSet(2, 1, 4, 3, 5)))
true
false
false
true
4.4. Seq
4.4.1. Set
HashSet:HashSet 是基于 HashMap 实现的,对 HashMap 做了一层简单的封装,而且只使用了HashMap 的 Key 来实现各种特性。元素特点唯一、无序。
ListSet:元素特点唯一、有序(元素添加的顺序)。
TreeSet:元素特点唯一、排序(按自然顺序排序)。
需求:
创建 HashSet 集合,存储元素 1, 4, 3, 2, 5, 5,然后打印集合
创建 ListSet 集合,存储 1, 4, 3, 2, 5, 5,然后打印集合
创建 SortedSet 集合,存储元素 1, 4, 3, 2, 5, 5,然后打印集合
val hashSet1 = HashSet(1,4,3,2,5,5)
val listSet1 = ListSet(1,4,3,2,5,5)
val sortSet1 = SortedSet(1,4,3,2,5,5)
println(hashSet1,listSet1,sortSet1)
(Set(5, 1, 2, 3, 4),ListSet(1, 4, 3, 2, 5),TreeSet(1, 2, 3, 4, 5))
4.4.2. Map
HashMap:元素特点 Key 唯一、无序。
ListMap:元素特点 Key 唯一、有序(元素添加(存储)的顺序)。
TreeMap:元素特点 Key 唯一、排序(按自然顺序排序)。
需求:
创建 HashMap 集合,存储元素 ("A", 1), ("B", 2), ("C", 3), ("C", 3),然后打印集合
创建 ListMap 集合,存储 ("A", 1), ("C", 3), ("B", 2), ("C", 3),然后打印集合
创建 TreeMap 集合,存储元素 ("A", 1), ("C", 3), ("B", 2), ("C", 3),然后打印集合
val hashMap1 = HashMap(("A"-> 1), ("B"-> 2), ("C"-> 3), ("C"->3))
val listMap1 = ListMap(("A", 1), ("C", 3), ("B", 2), ("C", 3))
val treeMap1 = TreeMap(("A", 1), ("C", 3), ("B", 2), ("C", 3))
println(hashMap1,listMap1,treeMap1)
(Map(A -> 1, B -> 2, C -> 3),ListMap(A -> 1, B -> 2, C -> 3),Map(A -> 1, B -> 2, C -> 3))
4.5. 数组Array
分为可变数组和不可变数组
4.5.1. 不可变数组
数组的长度不允许改变,数组的内容可以改变。
val|var 数组名 = new Array[元素类型](数组长度)
new的数组()写的是长度
val|var 数组名 = Array(元素1, 元素2, 元素3, ...)`
非new的数组()写的是元素
需求:
定义一个长度为 10 的整型数组,设置第 1 个元素为 5,设置第 2 个元素为 10,并打印这两个元素
定义一个包含 Java,Scala,Python 三个元素的数组,并打印数组长度
val arr1 = new Array[Int](10)
arr1(0)=5
arr1(1)=10
arr1.foreach(print)
println()
51000000000
4.5.2. 可变数组
数组的长度和内容都是可变的,可以往数组中添加、删除元素。
val|var 变量名 = ArrayBuffer[元素类型]()
val|var 变量名 = ArrayBuffer(元素1, 元素2, 元素3, ...)
需求:
定义一个长度为 0 的整型变长数组
定义一个包含 Hadoop、Hive、Spark 三个元素的变长数组
val arr2 = ArrayBuffer[Int](0)
println(arr2)
val arr3 = ArrayBuffer[String]("Hadoop","Hive","Spark")
arr3.foreach(println)
ArrayBuffer(0)
Hadoop
Hive
Spark
4.5.3. 增删改
针对可变数组
+= :添加单个元素
-= :删除单个元素
++= :追加多个元素到变长数组中
--= :移除变长数组中的多个元素
数组名(索引) = 新值 或者 数组名.update(索引, 新值) :修改元素
vb
`val arr4 = ArrayBuffer("Hadoop","Hive","Spark")
arr4+="Scala"
println(arr4)
arr4-="Hadoop"
println(arr4)
arr4++=Array("Linux","zookeeper")
println(arr4)
arr4--=Array("Scala","Linux")
println(arr4)
arr4 ++= ArrayBuffer("Phoenix", "Sqoop")
println(arr4)
arr4.update(1,"123")
println(arr4)
arr4(2)="234"
ArrayBuffer(Hadoop, Hive, Spark, Scala)
ArrayBuffer(Hive, Spark, Scala)
ArrayBuffer(Hive, Spark, Scala, Linux, zookeeper)
ArrayBuffer(Hive, Spark, zookeeper)
ArrayBuffer(Hive, Spark, zookeeper, Phoenix, Sqoop)
ArrayBuffer(Hive, 123, zookeeper, Phoenix, Sqoop)`
4.5.4. 遍历数组
val arr5 = Array(1, "2", 3.14, true, null)
遍历元素
for(i<-arr5){
println(i)
}
遍历索引
for(i<-arr5.indices){
println(i)
}
to 或 until
for(i <- 0 to arr5.size){
println(i)
}
arr5.foreach(println)
4.5.5. 常用方法
sum() :求和。
max() :求最大。
min() :求最小。
sorted() :排序(正序),返回一个新的数组。倒序可以先排序再反转。
reverse() :反转,返回一个新的数组。
var arr6=Array(4,1,3,2,5)
println(arr6.sum)
println(arr6.max)
println(arr6.min)
arr6.sorted.foreach(print)
println
arr6.sorted.reverse.foreach(print)
println
15
5
1
12345
54321
4.6. 元组Tuple
元组的长度和元素都是不可变的。
val|var 元组名 = (元素1, 元素2, 元素3, ...)
val|var 元组名 = 元素1 -> 元素2
注意:格式二只适用于元组中只有两个元素的情况
需求:
定义一个元组,包含学生的姓名和年龄
分别使用小括号以及箭头的方式来定义元组
val tuple1 = ("a",1,"123",true,false)
println(tuple1)
val tuple2 = "一个人"->12
println(tuple2)
(a,1,123,true,false)
(一个人,12)
4.6.1. 访问元素
元组名._n
val tuple3 = ("a",1,"123",true,false)
println(tuple3._1,tuple3._5)
(a,false)
4.7. 列表List
有序,可重复。
4.7.1. 不可变列表
列表的元素、长度都是不可变的。
val|var 列表名 = List(元素1, 元素2, 元素3, ...)
val|var 列表名 = Nil
val|var 列表名 = 元素1 :: 元素2 :: 元素n :: Nil
需求:
创建一个不可变列表,存放元素
使用 Nil 创建一个不可变的空列表
使用 :: 方法创建列表,包含 -2、-1 两个元素
val list1 = List(1,2,3,4,5)
val list2 = Nil
val list3 = -1 :: -1 :: 2 :: Nil
println(list3)
List(-1, -1, 2)
4.7.2. 可变列表
可变列表指的是列表的元素、长度都是可变的。
val|var 列表名 = ListBuffer[数据类型]()
val|var 列表名 = ListBuffer(元素1, 元素2, 元素3, ...
需求:
创建空的整型可变列表
创建一个可变列表,初始化时包含 1, "2", 3.14, true, null 元素
val list4 = ListBuffer[Any]()
val list5 = ListBuffer(1, "2", 3.14, true, null)
4.7.3. 常用方法
列表名(索引) 根据索引(索引从0开始),获取列表中的指定元素
列表名(索引) = 值 修改元素值
+= 添加单个元素
++= 追加多个元素到可变列表中
-= 删除单个元素
--= 移除可变列表中的多个元素
toList 将可变列表(ListBuffer)转换为不可变列表(List)
toArray 将可变列表(ListBuffer)转换为不可变数组(Array)
toBuffer 将可变列表(ListBuffer)转换为可变数组(BufferArray)
val list6 = ListBuffer[Int]()
list6+=123
list6.toList+=1 显然这样会报错,因为不可变列表不可添加和修改元素
println(list6)
需求:
定义一个列表 list1,包含以下元素: 1, "2", 3.14, true, null
使用 isEmpty 方法判断列表是否为空,并打印结果
再定义一个列表 list2,包含以下元素: "a", "b", "c"
使用 ++ 将两个列表拼接起来,并打印结果
使用 head 方法,获取列表的首个元素,并打印结果
使用 tail 方法,获取列表中除首个元素之外的其他所有元素,并打印结果
使用 reverse 方法,将列表元素反转,并打印结果
使用 take 方法,获取列表中的前缀元素,并打印结果
使用 drop 方法,获取列表中的后缀元素,并打印结果
使用 update 方法,修改指定位置元素,并返回一个修改后的新集合
val list7 = List(1, "2", 3.14, true, null)
println(list7.isEmpty)
val list8 = List("a", "b", "c")
println(list7 ++ list8)
println(list7.head)
println(list7.tail)
println(list7.reverse)
println(list7.take(3))前3个数
println(list7.drop(4))除了前4个数
println(list7.updated(0, "abc"))
false
List(1, 2, 3.14, true, null, a, b, c)
1
List(2, 3.14, true, null)
List(null, true, 3.14, 2, 1)
List(1, 2, 3.14)
List(null)
List(abc, 2, 3.14, true, null)
4.7.4. 扁平化
嵌套列表中的每个元素单独放到一个新的列表中。
需求:
定义一个列表,该列表有三个元素,分别为: List("Hello", "World") 、 List("Hello", "Scala") 、
List("Hello", "Spark")
使用 flatten 将这个列表转换为 List("Hello", "World", "Hello", "Scala", "Hello", "Spark")
val list9 = List(List("Hello", "World") ,List("Hello", "Scala"), List("Hello", "Spark"))
println(list9.flatten)
List(Hello, World, Hello, Scala, Hello, Spark)
4.7.5. 拉链与拉开
将两个列表合并成一个列表,列表的元素为元组。无法组成拉链的单个元素会被丢弃
将一个列表拆分成两个列表,两个列表被元组包含
需求:
定义列表 names,保存三个学生的姓名,分别为:张三、李四、王五
定义列表 ages,保存学生的年龄,分别为:18、19、20
使用 zip 将列表 names 和 ages 合并成一个列表 list
使用 unzip 将列表 list 拆分成包含两个列表的元组 tuple
val names = List("张三","李四","王五")
val ages = List(18,19,20)
val list= names.zip(ages)
println(list)
println(list.unzip)
List((张三,18), (李四,19), (王五,20))
(List(张三, 李四, 王五),List(18, 19, 20))
4.7.6. 转换字符串
toString :返回 List 中的所有元素的字符串
mkString :可以将元素以指定的分隔符拼接起来并返回,默认没有分隔符
需求:
定义一个列表,包含元素:1, 2, 3, 4
使用 toString 方法输出该列表元素
使用 mkString 方法指定分隔符为冒号,并输出该列表元素
var list10 = (1 to 4).toList
println(list10.toString())
println(list10.mkString(":"))
List(1, 2, 3, 4)
1:2:3:4
4.7.7. 交集/并集/差集
union并集(合并)操作,且不去重
intersect :表示对两个列表取交集(相同)
diff :表示对两个列表取差集(不同)
需求:
定义列表 list1,包含以下元素:1, 2, 3, 4
定义列表 list2,包含以下元素:3, 4, 5, 6
使用 union 获取 list1 和 list2 的并集
在上一步的基础上,使用 distinct 去除重复的元素
使用 intersect 获取 list1 和 list2 的交集
使用 diff 获取列表 list1 和 list2 的差集
var list11 = List(1,2,3,4)
var list12 = List(3,4,6,5)
println(list11.union(list12))
println(list11.union(list12).distinct)
println(list11.intersect(list12))
println(list11.diff(list12))
List(1, 2, 3, 4, 3, 4, 6, 5)
List(1, 2, 3, 4, 6, 5)
List(3, 4)
List(1, 2)
4.8. 集Set
唯一,自动去重。
4.8.1. 不可变集
元素和长度都不可变
val|var 集名 = Set[类型]()
val|var 集名 = Set(元素1, 元素2, 元素3, ...)
需求:
定义一个空的整型不可变集
定义一个不可变集,保存以下元素:1, 1, 2, 3, 4, 5
var set1 = Set(1,1,2,3,4,5)
println(set1)
4.8.2. 可变集
元素和长度都可变
val|var 集名 = mutable.Set[类型]()
val|var 集名 = mutable.Set(元素1, 元素2, 元素3, ...)
需求:
定义一个可变集,包含以下元素:1, 2, 3, 4
添加元素 5 到可变集中
添加元素 6, 7, 8 到可变集中
从可变集中移除元素 3
从可变集中移除元素 3, 5, 7
var set2 = mutable.Set(1, 2, 3, 4)
set2+=5
println(set2)
set2++=List(6,7,8)
println(set2)
set2-=3
println(set2)
set2--=Array(3,4,5)
println(set2)
Set(5, 1, 2, 3, 4)
Set(5, 1, 2, 3, 4)
Set(5, 1, 6, 2, 7, 3, 8, 4)
Set(5, 1, 6, 2, 7, 8, 4)
Set(1, 6, 2, 7, 8)
set2.update(2,false)删除
set2.update(10,true)添加
println(set2)
Set(1, 2, 6, 7, 8)
Set(1, 6, 10, 7, 8)
4.8.3. 语法格式 功能

4.9. 映射 Map
如果添加相同键元素,则后者的值会覆盖前者的值。
4.9.1. 不可变Map
Map 的元素、长度都是不可变的。
val|var map = Map(键1 -> 值1, 键2 -> 值2, 键3 -> 值3, ...)
val|var 集名 = Map((键1, 值1), (键2, 值2), (键3, 值3), ...)
需求:
定义一个 Map,包含以下元素: "张三" -> 18 , "李四" -> 19 , "王五" -> 20
获取键为张三的值
var map1 = Map("张三"-> 18,"李四"->19,"王五"->20)
var map2 = Map(("张三",18),("李四",19),("王五",20))
println(map1("张三"))
println(map2("李四"))
println(map1.getOrElse("zs","不存在"))
18
19
不存在
4.9.2. 可变Map
需求:
定义一个 Map,包含以下元素: "张三" -> 18 , "李四" -> 19 , "王五" -> 20
获取键为张三的值
修改张三的年龄为 28
var map3 = mutable.Map("张三" -> 18, "李四" -> 19, "王五" -> 20)
println(map3("张三"))
map3.update("张三", 29)
4.9.3. 遍历map
for(elem <- map3)println(elem)
for((k,v) <-map3)println(k,v)
map3.foreach(println)
4.9.4. 常见操作

需求:
定义一个可变 Map,包含以下元素: "张三" -> 18 , "李四" -> 19 , "王五" -> 20
获取张三的年龄
获取所有学生姓名
获取所有学生年龄
获取所有学生姓名和年龄
获取赵六的年龄,如果赵六不存在则返回 -1
新增一个学生: "赵六" -> 21
将李四从 Map 中移除
var map4 = mutable.Map("张三" -> 18 ,"李四" -> 19 , "王五" -> 20)
println(map4.get("张三"))
println(map4.keys)
println(map4.values)
for((k,v)<-map4)println(k,v)
println(map4.getOrElse("赵六", -1))
println(map4 += "赵六" -> 21)
println(map4 -= "李四")
Some(18)
Set(王五, 张三, 李四)
HashMap(20, 18, 19)
(王五,20)
(张三,18)
(李四,19)
-1
Map(赵六 -> 21, 王五 -> 20, 张三 -> 18, 李四 -> 19)
Map(赵六 -> 21, 王五 -> 20, 张三 -> 18)
4.10. range
val range01: Range.Inclusive = 1 to 5
for (i <- range01) println(i) 1 2 3 4 5
val range03: Range = 1 to 5 by 2
val range03: Range = Range(1, 5, 2)
for (i <- range03) println(i) 1 3 5
4.11. 函数式编程
遍历foreach
def foreach(f:(A) => Unit): Unit
简写形式
def foreach(函数)
4.11.1. 去重distinct
val list = List(1, 2, 2, 3, 4, 5, 6)
println(list.distinct) List(1, 2, 3, 4, 5, 6)
4.11.2. 映射map
def map[B](f: (A) => B): TraversableOnce[B]
// 简写形式
def map(函数对象)
val result2 = list.map(x => x * 2)
println(result2)
4.11.3. 扁平化flatmap
扁平化映射可以理解为先 map,然后再 flatten,它也是将来使用最多的操作,也是必须要掌握的。
def flatMap[B](f: (A) => GenTraversableOnce[B]): TraversableOnce[B]
简写形式
def flatMap(f: (A) => 待转换的集合的处理代码)
val list = List("hello world", "a new line", "the end")
val result3 = list.flatMap(s => s.split("\\s+"))
println(s"result3 = ${result3}")
// 根据空格拆分再合并
4.11.4. 过滤filter
def filter(f: (A) => Boolean): TraversableOnce[A]
val result1 = list.filter(x => x % 2 == 0)
4.11.5. 排序
sorted :按默认规则(升序)排序集合
sortBy :按指定属性排序集合
sortWith :按自定义规则排序集合
val sortby1 = List("01 zookeeper", "02 hadoop", "03 hive", "04 spark")
val resSort = sortby1.sortBy(x=>x.split("\\s+")(1))
val sortWith1 = List("01 zookeeper", "02 hadoop", "03 hive", "04 spark")
val resSort1 = sortWith1.sortWith((x, y) => x > y)
println(resSort1)//根据字典序排序从左至右
List(04 spark, 03 hive, 02 hadoop, 01 zookeeper)
4.11.6. 分组groupBy
val groupList1 = List("张三" -> "男", "李四" -> "女", "王五" -> "男")
val resGroupBy1 = groupList1.groupBy(x=>x._2)
println(resGroupBy1)返回Map集合
Map(男 -> List((张三,男), (王五,男)), 女 -> List((李四,女)))
4.11.7. 聚合reduce
def reduce[A1 >: A](op: (A1, A1) => A1): A1
简写形式
def reduce(op:(A1, A1) => A1)
val listRedu = (1 to 10).toList
使用 reduce 计算所有元素的和
val resRedu = listRedu.reduce((x, y) => x + y)
println(resRedu)
//55
println(listRedu.reduceLeft(_ - _))
//-53
println(listRedu.reduceRight(_ + _))
//55
4.11.8. 折叠
def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1
简写形式
def fold(初始值)(op:(A1, A1) => A1)
val listFold = (1 to 10).toList
val resFold = listFold.fold(10)((x, y) => x + y)//10为起始值
println(resFold)
//65
println(list.foldLeft(10)(_ - _))
println(list.foldRight(10)(_ - _))