首先看一下整个集合体系结构,这个结构与Java的集合体系非常相似
image.png

集合

Scala中的集合是分成可变和不可变两类集合的

  • 其中可变集合就是说,集合的元素可以动态修改
  • 而不可变集合就是说,集合的元素在初始化之后,就无法修改了

    可变集合

    在scala.collection.mutable这个包下面

    不可变集合(默认)

    在scala.collection.immutable这个包下面
    我们在创建集合的时候,如果不指定具体的包名,默认会使用不可变集合

    Set

    Set代表一个没有重复元素的集合
    Set集合分为可变的和不可变的集合,默认情况下使用的是不可变集合

Set可以直接使用,并且不需要使用new关键字

  1. val set = Set(1, 2, 3)
  2. 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)
    }

  }

image.png

List(不可变)

List代表一个不可变的列表

  def main(args: Array[String]): Unit = {

    val list = List(1, 2, 3, 4)
    for (elem <- list) {
      println(elem)
    }

  }

image.png
针对List有headtail以及::这几个操作

  def main(args: Array[String]): Unit = {
    val list = List(1, 2, 3, 4)

    println(list.head)
    println(list.tail)
    println(list.head :: list.tail)

  }

image.png

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)
  }

image.png

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)

  }

image.png
遍历Map
1、遍历map的entrySet

    for (elem <- ages) {
      println(elem)
    }

image.png

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

image.png
2、遍历key

    for (k <- ages.keySet) {
      println(k)
    }

image.png
3、遍历value

    for (v <- ages.values) {
      println(v)
    }

image.png
最后看一下Map的几个子类
HashMap、SortedMap和LinkedHashMap

HashMap

是一个按照key的hash值进行排列存储的map

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)
  }

image.png

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)
  }

image.png

数组

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)
    }
  }

image.png

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)
  }

image.png

注意: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)
  }

image.png

总结

  • 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:长度不可变,里面的元素也不可变