「这是我参与11月更文挑战的第30天,活动详情查看:2021最后一次更文挑战」。
一、集合
1、集合简介
-
Scala 的集合有三大类:序列 Seq、集 Set、映射 Map,所有的集合都扩展自 Iterable特质。
-
对于几乎所有的集合类,Scala 都同时提供了可变和不可变的版本,分别位于以下两个包
-
不可变集合:scala.collection.immutable
-
可变集合: scala.collection.mutable
-
-
Scala 不可变集合,就是指该集合对象不可修改,每次修改就会返回一个新对象,而不会对原对象进行修改。类似于java 中的 String 对象
-
可变集合,就是这个集合可以直接对原对象进行修改,而不会返回新的对象。类似于 java 中 StringBuilder 对象
1.1、不可变集合继承图
-
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.2、可变集合继承图
2、数组
2.1、不可变数组
-
第一种方式定义数组
定义:val arr1 = new Array[Int](10)- new 是关键字
- [Int]是指定可以存放的数据类型,如果希望存放任意数据类型,则指定 Any
- (10),表示数组的大小,确定后就不可以变化
-
案例实操
object TestArray{ def main(args: Array[String]): Unit = { //(1)数组定义 val arr01 = new Array[Int](4) println(arr01.length) // 4 //(2)数组赋值 //(2.1)修改某个元素的值 arr01(3) = 10 //(2.2)采用方法的形式给数组赋值 arr01.update(0,1) //(3)遍历数组 //(3.1)查看数组 println(arr01.mkString(",")) //(3.2)普通遍历 for (i <- arr01) { println(i) } //(3.3)简化遍历 def printx(elem:Int): Unit = { println(elem) } arr01.foreach(printx) // arr01.foreach((x)=>{println(x)}) // arr01.foreach(println(_)) arr01.foreach(println) //(4)增加元素(由于创建的是不可变数组,增加元素,其实是产生新的数组) println(arr01) val ints: Array[Int] = arr01 :+ 5 println(ints) } } -
第二种方式定义数组
val arr1 = Array(1, 2)
- 在定义数组时,直接赋初始值
- 使用 apply 方法创建数组对象
-
案例实操
object TestArray{ def main(args: Array[String]): Unit = { var arr02 = Array(1, 3, "bobo") println(arr02.length) for (i <- arr02) { println(i) } } }
2.2、可变数组
-
定义变长数组
val arr01 = ArrayBuffer[Any](3, 2, 5)
- [Any]存放任意数据类型
- (3, 2, 5)初始化好的三个元素
- ArrayBuffer 需要引入 scala.collection.mutable.ArrayBuffer
-
案例实操
-
ArrayBuffer 是有序的集合
-
增加元素使用的是 append 方法(),支持可变参数
import scala.collection.mutable.ArrayBuffer object TestArrayBuffer { def main(args: Array[String]): Unit = { //(1)创建并初始赋值可变数组 val arr01 = ArrayBuffer[Any](1, 2, 3) //(2)遍历数组 for (i <- arr01) { println(i) } println(arr01.length) // 3 println("arr01.hash=" + arr01.hashCode()) //(3)增加元素 //(3.1)追加数据 arr01.+=(4) //(3.2)向数组最后追加数据 arr01.append(5,6) //(3.3)向指定的位置插入数据 arr01.insert(0,7,8) println("arr01.hash=" + arr01.hashCode()) //(4)修改元素 arr01(1) = 9 //修改第 2 个元素的值 println("--------------------------") for (i <- arr01) { println(i) } println(arr01.length) // 5 } }
-
2.3、不可变数组与可变数组的转换
-
说明
arr1.toBuffer //不可变数组转可变数组
arr2.toArray //可变数组转不可变数组
-
arr2.toArray 返回结果才是一个不可变数组,arr2 本身没有变化
-
arr1.toBuffer 返回结果才是一个可变数组,arr1 本身没有变化
-
-
案例实操
object TestArrayBuffer { def main(args: Array[String]): Unit = { //(1)创建一个空的可变数组 val arr2 = ArrayBuffer[Int]() //(2)追加值 arr2.append(1, 2, 3) println(arr2) // 1,2,3 //(3)ArrayBuffer ==> Array //(3.1)arr2.toArray 返回的结果是一个新的定长数组集合 //(3.2)arr2 它没有变化 val newArr = arr2.toArray println(newArr) //(4)Array ===> ArrayBuffer //(4.1)newArr.toBuffer 返回一个变长数组 newArr2 //(4.2)newArr 没有任何变化,依然是定长数组 val newArr2 = newArr.toBuffer newArr2.append(123) println(newArr2) } }
2.4、多维数组
-
多维数组定义
val arr = Array.ofDim[Double](3,4)说明:二维数组中有三个一维数组,每个一维数组中有四个元素
-
案例实操
object DimArray { def main(args: Array[String]): Unit = { //(1)创建了一个二维数组, 有三个元素,每个元素是,含有 4 个元素一维数组() val arr = Array.ofDim[Int](3, 4) arr(1)(2) = 88 //(2)遍历二维数组 for (i <- arr) { //i 就是一维数组 for (j <- i) { print(j + " ") } println() } } }
3、列表 List
3.1、不可变 List
-
说明
- List 默认为不可变集合
- 创建一个 List(数据有顺序,可重复)
- 遍历 List
- List 增加数据
- 集合间合并:将一个整体拆成一个一个的个体,称为扁平化
- 取指定数据
- 空集合 Nil
-
案例实操
object TestList { def main(args: Array[String]): Unit = { //(1)List 默认为不可变集合 //(2)创建一个 List(数据有顺序,可重复) val list: List[Int] = List(1,2,3,4,3) //(7)空集合 Nil val list5 = 1::2::3::4::Nil //(4)List 增加数据 //(4.1)::的运算规则从右向左 //val list1 = 5::list val list1 = 7::6::5::list //(4.2)添加到第一个元素位置 val list2 = list.+:(5) //(5)集合间合并:将一个整体拆成一个一个的个体,称为扁平化 val list3 = List(8,9) //val list4 = list3::list1 val list4 = list3:::list1 //(6)取指定数据 println(list(0)) //(3)遍历 List //list.foreach(println) //list1.foreach(println) //list3.foreach(println) //list4.foreach(println) list5.foreach(println) } }
3.2、可变 ListBuffer
-
说明
- 创建一个可变集合 ListBuffer
- 向集合中添加数据
- 打印集合数据
-
案例实操
import scala.collection.mutable.ListBuffer object TestList { def main(args: Array[String]): Unit = { //(1)创建一个可变集合 val buffer = ListBuffer(1,2,3,4) //(2)向集合中添加数据 buffer.+=(5) buffer.append(6) buffer.insert(1,2) //(3)打印集合数据 buffer.foreach(println) //(4)修改数据 buffer(1) = 6 buffer.update(1,7) //(5)删除数据 buffer.-(5) buffer.-=(5) buffer.remove(5) } }
4、Set 集合
默认情况下,Scala 使用的是不可变集合,如果你想使用可变集合,需要引用scala.collection.mutable.Set 包
4.1、不可变 Set
-
说明
-
Set 默认是不可变集合,数据无序
-
数据不可重复
-
遍历集合
-
-
案例实操
object TestSet { def main(args: Array[String]): Unit = { //(1)Set 默认是不可变集合,数据无序 val set = Set(1,2,3,4,5,6) //(2)数据不可重复 val set1 = Set(1,2,3,4,5,6,3) //(3)遍历集合 for(x<-set1){ println(x) } } }
4.2、可变 mutable.Set
-
说明
- 创建可变集合 mutable.Set
- 打印集合
- 集合添加元素
- 向集合中添加元素,返回一个新的 Set
- 删除数据
-
案例实操
object TestSet { def main(args: Array[String]): Unit = { //(1)创建可变集合 val set = mutable.Set(1,2,3,4,5,6) //(3)集合添加元素 set += 8 //(4)向集合中添加元素,返回一个新的 Set val ints = set.+(9) println(ints) println("set2=" + set) //(5)删除数据 set-=(5) //(2)打印集合 set.foreach(println) println(set.mkString(",")) } }
5、Map 集合
Scala 中的 Map 和 Java 类似,也是一个散列表,它存储的内容也是键值对(key-value)映射
5.1、不可变 Map
-
说明
- 创建不可变集合 Map
- 循环打印
- 访问数据
- 如果 key 不存在,返回 0
-
案例实操
object TestMap { def main(args: Array[String]): Unit = { // Map //(1)创建不可变集合 Map val map = Map( "a"->1, "b"->2, "c"->3 ) //(3)访问数据 for (elem <- map.keys) { // 使用 get 访问 map 集合的数据,会返回特殊类型 Option(选项): 有值(Some),无值(None) println(elem + "=" + map.get(elem).get) } //(4)如果 key 不存在,返回 0 println(map.get("d").getOrElse(0)) println(map.getOrElse("d", 0)) //(2)循环打印 map.foreach((kv)=>{println(kv)}) } }
5.2、可变 Map
-
说明
- 创建可变集合
- 打印集合
- 向集合增加数据
- 删除数据
- 修改数据
-
案例实操
object TestSet { def main(args: Array[String]): Unit = { //(1)创建可变集合 val map = mutable.Map( "a"->1, "b"->2, "c"->3 ) //(3)向集合增加数据 map.+=("d"->4) // 将数值 4 添加到集合,并把集合中原值 1 返回 val maybeInt: Option[Int] = map.put("a", 4) println(maybeInt.getOrElse(0)) //(4)删除数据 map.-=("b", "c") //(5)修改数据 map.update("d",5) map("d") = 5 //(2)打印集合 map.foreach((kv)=>{println(kv)}) } }
6、元组
-
说明
元组也是可以理解为一个容器,可以存放各种相同或不同类型的数据。说的简单点,就是将多个无关的数据封装为一个整体,称为元组。
注意:元组中最大只能有 22 个元素。
-
案例实操
-
声明元组的方式:(元素 1,元素 2,元素 3)
-
访问元组
-
Map 中的键值对其实就是元组,只不过元组的元素个数为 2,称之为对偶
object TestTuple { def main(args: Array[String]): Unit = { //(1)声明元组的方式:(元素 1,元素 2,元素 3) val tuple: (Int, String, Boolean) = (40,"bobo",true) //(2)访问元组 //(2.1)通过元素的顺序进行访问,调用方式:_顺序号 println(tuple._1) println(tuple._2) println(tuple._3) //(2.2)通过索引访问数据 println(tuple.productElement(0)) //(2.3)通过迭代器访问数据 for (elem <- tuple.productIterator) { println(elem) } //(3)Map 中的键值对其实就是元组,只不过元组的元素个数为 2,称之为 对偶 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)}) } }
-