首先看一下整个集合体系结构,这个结构与Java的集合体系非常相似
集合
Scala中的集合是分成可变和不可变两类集合的
- 其中可变集合就是说,集合的元素可以动态修改
- 而不可变集合就是说,集合的元素在初始化之后,就无法修改了
可变集合
在scala.collection.mutable这个包下面不可变集合(默认)
在scala.collection.immutable这个包下面
我们在创建集合的时候,如果不指定具体的包名,默认会使用不可变集合Set
Set代表一个没有重复元素的集合
Set集合分为可变的和不可变的集合,默认情况下使用的是不可变集合
Set可以直接使用,并且不需要使用new关键字
val set = Set(1, 2, 3)println(set)
来看一下Scala的文档,你会发现这个Set不仅仅是一个接口,它还是一个Object 在这大家可以这样理解,只要前面带有object的,可以直接创建对象,并且不需要使用new关键字,所以set可以直接使用。
注意:默认情况下直接创建的set集合是一个不可变集合,在这可以看到是在immutable包里面的,不可变集合中的元素一经初始化,就不能改变了,所以初始化后再向里面添加元素s+=4就报错了。
但是注意,我使用s + 4这种操作是可以的,因为 s + 4 返回的是一个新的集合了,相当于在之前的集合的基础上,创建一个新的集合,新的集合包含之前集合的元素和我们新增的4这个元素
如果想要创建一个可变的set集合,可以使用mutable包下面的set集合,显式指定包名
scala> val s = Set(1, 2, 3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)
scala> s+=4
<console>:13: error: value += is not a member of scala.collection.immutable.Set[Int]
Expression does not convert to assignment because receiver is not assignable.
s+=4
^
scala> s+4
res1: scala.collection.immutable.Set[Int] = Set(1, 2, 3, 4)
scala> val s = scala.collection.mutable.Set(1,2,3)
s: scala.collection.mutable.Set[Int] = Set(1, 2, 3)
scala> s+=4
res2: s.type = Set(1, 2, 3, 4)
HashSet
集合中的元素不重复、无序
HashSet集合分为可变和不可变之分,immutable包下面的是不可变的,后期无法新增元素
scala> val s = new scala.collection.mutable.HashSet[Int]()
s: scala.collection.mutable.HashSet[Int] = Set()
scala> s+=1
res3: s.type = Set(1)
scala> s+=2
res4: s.type = Set(1, 2)
scala> s+=(3)
res5: s.type = Set(1, 2, 3)
scala> s+=(5)
res6: s.type = Set(1, 5, 2, 3)
在这里可以使用new关键字,也可以不使用,因为HashSet既是class,又是object 如果在创建集合的时候就初始化了元素,则可以省略泛型的定义,集合会自动识别元素的类型
LinkedHashSet(可变)
集合中的元素不重复、有序,它会用一个链表维护插入顺序,可以保证集合中元素是有序的
LinkedHashSet只有可变的,没有不可变的
scala> val s = new scala.collection.mutable.LinkedHashSet[Int]()
s: scala.collection.mutable.LinkedHashSet[Int] = Set()
scala> s+=1
res7: s.type = Set(1)
scala> s+=2
res8: s.type = Set(1, 2)
scala> s+=5
res9: s.type = Set(1, 2, 5)
scala> s+=3
res10: s.type = Set(1, 2, 5, 3)
SortedSet
集合中的元素不重复、有序,它会自动根据元素来进行排序
SortedSet分为可变集合和不可变集合
scala> val s = scala.collection.mutable.SortedSet[String]()
s: scala.collection.mutable.SortedSet[String] = TreeSet()
scala> s +=("c")
res11: s.type = TreeSet(c)
scala> s +=("a")
res12: s.type = TreeSet(a, c)
scala> s +=("b")
res13: s.type = TreeSet(a, b, c)
从这可以看出来SortedSet集合中的元素是按照元素的字典顺序排序的
针对里面这些Set集合,如果想要迭代他们里面的元素,可以使用for循环直接迭代
def main(args: Array[String]): Unit = {
val s = Set(1, 2, 3)
for (i <- s) {
println(i)
}
}
List(不可变)
List代表一个不可变的列表
def main(args: Array[String]): Unit = {
val list = List(1, 2, 3, 4)
for (elem <- list) {
println(elem)
}
}

针对List有head、tail以及::这几个操作
def main(args: Array[String]): Unit = {
val list = List(1, 2, 3, 4)
println(list.head)
println(list.tail)
println(list.head :: list.tail)
}

| head | 表示获取List中的第一个元素 |
|---|---|
| tail | 表示获取List中第一个元素之后的所有元素 |
| :: | 通过::操作符,可以将head和tail的结果合并成一个List |
:: 这种操作符要清楚,在spark源码中是有体现的,一定要能够看懂
ListBuffer(可变)
可以支持动态增加或者移除元素
def main(args: Array[String]): Unit = {
//val listBuffer = new ListBuffer[Int]
val lb = ListBuffer(1)
lb += 2
lb += 3
lb -= 3
println(lb)
}
Map
Map是一种可迭代的键值对(key/value)结构
Map分为可变和不可变,默认情况下使用的是不可变Map
def main(args: Array[String]): Unit = {
//创建一个可变map
val ages = scala.collection.mutable.Map("jack" -> 20, "tom" -> 25, "john" -> 30)
println(ages)
//查询key
println(ages("jack"))
//查询不存在的key会报错
//println(ages("jack1"))
//查询可能不存在的key
println(if (ages.contains("jack1")) ages("jack1") else null)
//查询可能不存在的key,推荐
println(ages.getOrElse("jack1", null))
//修改元素
ages("jack") = 21
println(ages)
//添加元素
ages += ("zs" -> 15, "ls" -> 16)
println(ages)
//删除元素
ages -= ("ls")
println(ages)
}

遍历Map
1、遍历map的entrySet
for (elem <- ages) {
println(elem)
}

for ((k, v) <- ages) {
println(k + " " + v)
}

2、遍历key
for (k <- ages.keySet) {
println(k)
}

3、遍历value
for (v <- ages.values) {
println(v)
}

最后看一下Map的几个子类
HashMap、SortedMap和LinkedHashMap
HashMap
SortedMap
可以自动对Map中的key进行排序【有序的map】
SortedMap是不可变的
def main(args: Array[String]): Unit = {
val ages = scala.collection.immutable.SortedMap("b" -> 30, "a" -> 15, "c" -> 25)
println(ages)
}
LinkedHashMap(可变)
可以记住插入的key-value的顺序
LinkedHashMap是可变的
def main(args: Array[String]): Unit = {
val ages = new mutable.LinkedHashMap[String, Int]
ages("b") = 30
ages("a") = 15
ages("c") = 25
println(ages)
}
数组
Array
Scala中Array的含义与Java中的数组类似,长度不可变
由于Scala和Java都是运行在JVM中,双方可以互相调用,因此Scala数组的底层实际上就是Java数组
数组初始化后,长度就固定下来了,而且元素全部根据其类型进行初始化
def main(args: Array[String]): Unit = {
//创建一个长度为5的数组
val arr = new Array[Int](5)
println(arr(0))
println(arr(1))
//也可以直接使用Array()创建数组,元素类型自动推断
val arr2 = Array("hello", "world")
for (elem <- arr2) {
println(elem)
}
}
ArrayBuffer(长度可变)
Scala中ArrayBuffer与Java中的ArrayList类似,长度可变
def main(args: Array[String]): Unit = {
val arr = new ArrayBuffer[Int]()
//添加,可以添加一个元素,或者多个元素
arr += 1
arr += (2, 3, 4, 5)
println(arr)
//在指定位置插入元素(这种操作效率很低,因为需要移动指定位置后的所有元素)
arr.insert(3, 30)
println(arr)
//移除元素
arr.remove(3)
println(arr)
}

注意:Array与ArrayBuffer可以互相进行转换 b.toArray:ArrayBuffer转Array
a.toBuffer:Array转ArrayBuffer
数组常见操作
def main(args: Array[String]): Unit = {
val arr = ArrayBuffer(1, 2, 3, 4, 5)
println(arr)
//1、迭代集合
for (elem <- arr) {
println(elem)
}
//2、使用角标迭代
for (i <- 0 until arr.length) {
println(arr(i))
}
//3、求和
println(arr.sum)
//求最大值
println((arr.max))
//排序
//scala.util.Sorting.quickSort(arr)
}
Tuple(类型可变)
Tuple:称之为元组,它与Array类似,长度都是不可变的,但与数组不同的是元组可以包含不同类型的元素
Tuple中的元素角标从 1 开始
注意:目前 Scala 支持的元组最大长度为 22 ,对于更大长度可以使用集合或数组
def main(args: Array[String]): Unit = {
//val t=Tuple3(1,2.2,"hehe")
val t = (1, 3.14, "hehe")
println(t)
println(t._1)
println(t._2)
println(t._3)
}
总结
- HashSet:集合中的元素不重复、无序
- LinkedHashSet:集合中的元素不重复、有序,它会用一个链表维护插入顺序,可以保证集合中元素是有序的
- SortedSet:集合中的元素不重复、有序,它会自动根据元素来进行排序
- HashMap:是一个按照key的hash值进行排列存储的map
- SortedMap:可以自动对Map中的key进行排序【有序的map】
- LinkedHashMap:可以记住插入的key-value的顺序
可变集合:LinkedHashSet、ListBuffer、ArrayBuffer、LinkedHashMap
不可变集合:List、SortedMap
可变+不可变集合:Set、HashSet、SortedSet、Map、HashMap
还有两个编外人员:
Array、Tuple
Array:长度不可变,里面的元素可变
Tuple:长度不可变,里面的元素也不可变
