目录
一 基础概念
- Scala 的集合有三大类:序列 Seq、集Set、映射 Map,所有的集合都扩展自 Iterable
特质。
- 对于几乎所有的集合类,Scala 都同时提供了可变和不可变的版本,分别位于以下两个包
不可变集合:scala.collection.immutable 可变集合 scala.collection.mutable
- Scala 不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象, 而不会对原对象进行修改。类似于 java 中的 String 对象
- 可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于 java 中 StringBuilder 对象
建议:在操作集合的时候,不可变用符号,可变用方法
不可变集合继承图
- Set 、 Map是Java中 也 有 的 集 合
- Seq 是 Java 没有的,我们发现 List 归属到Seq 了,因此这里的 List 就和 Java 不是同一个概念了
- 我们前面的for 循环有一个 1 to 3,就是 IndexedSeq 下的 Range
- String 也是属于 IndexedSeq
- 我们发现经典的数据结构比如 Queue 和 Stack 被归属到 LinearSeq(线性序列)
- 大家注意Scala 中的 Map 体系有一个 SortedMap,说明 Scala 的 Map 可以支持排序
IndexedSeq 和LinearSeq 的区别:
① IndexedSeq 是通过索引来查找和定位,因此速度快,比如String 就是一个索引集合,通过索引即可定位
② LinearSeq 是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找
可变集合继承图
二 数组
1 不可变数组
1.1 第一种定义方法
"""
|new 是关键字
|Int 是泛型
|10 是数量,确定后不可改变
""".stripMargin
val arr1 = new Array[Int](10)
arr1.foreach(print) // 0000000000
一些常用的操作
val arr1 = new Array[Int](10)
println(arr1.length) // 10
arr1(0) = 1 // 根据索引赋值,使用小括号,而不是中括号
arr1.update(2, 3) // 使用方法,将索引为2的值赋为3
println(arr1.mkString(",")) // 字符串格式化输出数组 -> 1,0,3,0,0,0,0,0,0,0
for (elem <- arr1) { // 普通输出 arr1.for
print(elem + "\t") // 1 0 3 0 0 0 0 0 0 0
}
arr1.foreach(print) // 简化输出
// 增加元素(由于创建的是不可变数组,增加元素,其实是产生新的数组)
println(arr1.mkString(",")) // 1,0,3,0,0,0,0,0,0,0
val ints: Array[Int] = arr1 :+ 5
println(ints.mkString(",")) // 1,0,3,0,0,0,0,0,0,0,5
1.2 第二种定义方法
- 在定义数组时,直接赋初始值
- 使用apply 方法创建数组对象
val arr2 = Array(1, 2)
print(arr2.mkString(",")) // 1,2
val arr3 = Array(1, 2, "haha")
print(arr3.mkString(",")) // 1,2,haha
2 可变数组
2.1 定义方法
- [Any]存放任意数据类型
- (3, 2, 5)初始化好的三个元素
- ArrayBuffer 需要引入 scala.collection.mutable.ArrayBuffer
val arr01 = ArrayBuffer[Any](3, 2, 5)
一些常用方法
val buffer: ArrayBuffer[Any] = ArrayBuffer[Any](1, 2, 3)
buffer.append("haha") // 尾部增加元素
buffer.append(4, 5) // 尾部增加元素
buffer.+=(6)
println(buffer.mkString(" ")) // 1 2 3 haha 4 5 6
// 在指定位置插入元素
buffer.insert(0, "insert0", "insert1")
println(buffer.mkString(" ")) // insert0 insert1 1 2 3 haha 4 5 6
// 修改元素
buffer(0) = "update" // 修改第一个元素的值
println(buffer.mkString(" ")) // update insert1 1 2 3 haha 4 5 6
3 不可变数组与可变数组的转换
// 可变数组
val buffer: ArrayBuffer[Any] = ArrayBuffer[Any](1, 2, 3)
//不可变数组
val a1 = new Array[Int](10)
// 转为不可变数组
val array: Array[Any] = buffer.toArray
// 转为可变数组
val buffer2: mutable.Buffer[Int] = a1.toBuffer
4 多维数组
4.1 定义
- 二维数组中有三个一维数组,每个一维数组中有四个元素
val arr = Array.ofDim[Double](3,4)
val arr2d = Array.ofDim[Double](3, 4)
arr2d(0)(0) = 1
for (row <- arr2d) {
for (col <- row) {
print(col + "\t")
}
println()
}
"""
|1.0 0.0 0.0 0.0
|0.0 0.0 0.0 0.0
|0.0 0.0 0.0 0.0
""".stripMargin
三 列表 List
1 不可变List
- List 默认为不可变集合
- 创建一个 List(数据有顺序,可重复)
- 遍历 List
- List 增加数据
- 集合间合并:将一个整体拆成一个一个的个体,称为扁平化
- 取指定数据
- 空集合Nil
1.1 使用方法
// List 默认为不可变集合
val ints = List(1, 2, 3, 4, 5, 4)
1.2 空集合
val list1 = 1 :: 2 :: 3 :: Nil
val list2 = Nil
println(list1) // List(1, 2, 3)
println(list2) // List()
1.3 List 增加数据
// List 增加数据,::的运算规则从右向左
val list23 = Nil
val list24 = 0 :: list23 // List(0)
val list25 = 2 :: 1 :: list24
println(list25) // List(2, 1, 0)
val list = List(1, 2, 4, 5, 4)
val list2: List[Int] = list.+:(0) // z在列表头部加数据
println(list2) // List(0, 1, 2, 4, 5, 4)
1.4 集合间合并
// 集合间合并
val l1 = List(1, 2)
val l2 = List(3, 4)
println(l1 :: l2) // List(List(1, 2), 3, 4)
println(l1 ::: l2) // List(1, 2, 3, 4)
println(l1 ++ l2) // List(1, 2, 3, 4)
1.5 取指定数据
val l1 = List(1, 2)
println(l1(0)) // 1
1.6 遍历List
val l1 = List(1, 2)
l1.foreach(println)
//1
//2
2 可变ListBuffer
val bufferList = ListBuffer(1, 2, 3, 4)
println(bufferList.mkString(" ")) // 1 2 3 4
bufferList.append(1)
bufferList.+=(5)
bufferList.insert(0, 0)
println(bufferList.mkString(" ")) // 0 1 2 3 4 1 5
bufferList(1) = 2
println(bufferList.mkString(" ")) //0 2 2 3 4 1 5
// 返回一个新列表,里面不包含5
val newBuffer = bufferList.-(5) // 0 2 2 3 4 1
println("newBuffer " + newBuffer.mkString(" "))
// 则直接在原始列表 bufferList 中移除元素 5,并返回一个指向原始列表的引用
bufferList.-=(5)
// 移除索引为 5 的元素,并返回被移除的元素
bufferList.remove(5)
println(bufferList.mkString(" "))// 0 2 2 3 4
四 Set集合
默认情况下, Scala 使用的是不可变集合, 如果你想使用可变集合, 需要引用
scala.collection.mutable.Set 包
1 不可变Set
// 数据不可重复
val set: Set[Int] = Set(1, 2, 4, 5, 4)
println(set) //Set(1, 2, 4, 5)
println(set.mkString(" ")) // 1 2 4 5
set.foreach(println)
2 可变mutable.Set
val set: mutable.Set[Int] = mutable.Set(1, 2, 3, 4)
println(set.mkString(" ")) // 1 2 3 4
set += 8
println(set.mkString(" ")) // 1 2 3 4 8
// 返回一个新set
val newSet = set.+(9)
println(newSet.mkString(" ")) // 9 1 2 3 4 8
// 删除
set -= (9)
println(set.mkString(" ")) //1 2 3 4 8
五 Map集合
Scala 中的 Map 和 Java 类似,也是一个散列表,它存储的内容也是键值对(key-value) 映射
1 不可变Map
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
for (elem <- map.keys) {
print(elem + "=" + map.get(elem).get + "\t") //a=1 b=2 c=3
}
// 使用 get 访问 map 集合的数据,
// 会返回特殊类型 Option(选项):有值(Some),无值(None)
println(map.get("d")) // None
// getOrElse 如果有值,返回值,没有值,返回指定默认值
println(map.get("a")) // Some(1)
println(map.get("a").getOrElse(0)) // 1
println(map.get("d").getOrElse(0)) // 0
println(map.mkString(" ")) // a -> 1 b -> 2 c -> 3
// 循环打印
map.foreach((kv) => {print(kv + " ")}) // (a,1) (b,2) (c,3)
2 可变Map
//(1)创建可变集合
val map = mutable.Map("a" -> 1, "b" -> 2, "c" -> 3)
//(2)向集合增加数据
map.+=("d"->4)
// 将数值 4 添加到集合,并把集合中原值 1 返回
val maybeInt: Option[Int] = map.put("a", 4)
println(maybeInt.getOrElse(0)) // 1
//(3)删除数据
map.-=("b", "c")
//(4)修改数据
map.update("d",5) map("d") = 5
//(5)打印集合
map.foreach((kv)=>{println(kv)})
六 元组
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。
注意:元组中最大只能有 22 个元素。
声明方式
val tuple: (Int, String, Boolean) = (40,"bobo",true)
val t: (String, Int, Boolean) = ("mingyu", 10, true)
// 访问元组
println(t._1) // mingyu
println(t._2) // 10
println(t._3) // true
// 根据索引访问元组
println(t.productElement(0)) // mingyu
// 通过迭代器访问元组
for (elem <- t.productIterator) {
println(elem)
}
"""
|Map 中的键值对其实就是元组,
|只不过元组的元素个数为 2,称之为
|对偶
""".stripMargin
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
val map1 = Map(("a", 1), ("b", 2), ("c", 3))
map.foreach(tuple => println(tuple._1 + "=" + tuple._2))
"""
|a=1
|b=2
|c=3
""".stripMargin