第7章 Scala集合
7.1 简介
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jGLaLwcb-1687453296527)(assets/image-20230621230820-f1hspe9.png)]
-
scala.collection.immutable
-
scala.collection.mutable
7.2 数组
-
不可变数组
package chapter07 object Test01_ImmutableArray { def main(args: Array[String]): Unit = { // 1. 创建数组 val arr: Array[Int] = new Array[Int](10) arr(9) = 9 println(arr.mkString(",")) // 另一种创建方式 val arr2 = Array[Int](1, 2, 3, 4, 65) // 2. 数组操作-(由于是不可变数组,增删不能改变)改查 // 访问元素 println(arr2.mkString(",")) arr2(0) = 100 println(arr2.apply(0)) arr2.update(0, 199) println(arr2.mkString(",")) // 3. 数组的遍历 // for循环 for (i <- arr2.indices) { println(arr2(i)) } // 增强for循环 for (ele <- arr2) { println(ele) } // 迭代器 val iterator: Iterator[Int] = arr2.iterator println("++++++++++迭代器+++++++++++++++") while (iterator.hasNext) { println(iterator.next()) } // foreach arr2.foreach((ele: Int) => { println(ele) }) arr2.foreach(println(_)) println(arr2.mkString("----")) // 3. 添加元素,由于是不可变数组,因此添加元素之后,生成一个新的数组 // 30------199------2------3------4------65------2 val array: Array[Any] = arr2.:+(2).+:(30) // 往后追加元素 :+,往前追加元素 +: 2 +: arr2 :+ 10 :+ 10 println(array.mkString("------")) arr2 ++ Array(2) } }
-
可变数组
package chapter07 import scala.collection.mutable import scala.collection.mutable.ArrayBuffer object Test02_mutableArrayBuff { def main(args: Array[String]): Unit = { // 1. 创建一个可变数组,无任何元素 val arr = new ArrayBuffer[Int]() println(arr.mkString("--")) arr += 10 println(arr.mkString("--")) // 另一种创建方法 val arr2: ArrayBuffer[Int] = ArrayBuffer(19, 10, 2) println(arr2) println(arr2.mkString("===")) // 2. 访问元素 println(arr2(0)) // 3. 添加元素 val newArr = arr2 :+ 10 println(newArr == arr2) println(arr2) // 不建议这样的操作,建议arr2 += 10 val arr3 = arr2 += 10 println(arr3 == arr2) 101 +=: arr3 println(arr3) // 可变集合推荐调用方法 arr3.append(10, 1999) arr3.prepend(10092) arr3.insert(2, 22222) println(arr3) // 添加一个数组 arr3.insertAll(1, arr) println(arr3) // 4. 删除元素,指定位置 arr3.remove(1) println(arr3) arr3.remove(1, 2) println(arr3) // 删除特定值 arr3 -= 10 println(arr3) // 5. 可变数组与不可变数组之间的转换 val arr5 = ArrayBuffer(10, 2, 3, 1) val newArr5: Array[Int] = arr5.toArray println(newArr5.mkString("-")) val buffer: mutable.Buffer[Int] = newArr5.toBuffer println(buffer) println(newArr5) } }
-
多维度数组
package chapter07 object Test03_MulArray { def main(args: Array[String]): Unit = { // 创建2维数组 val array: Array[Array[Int]] = Array.ofDim[Int](2, 3) // 访问元素 array(0)(2) = 10 println(array.mkString("-")) for (i <- 0 until array.length; j <- 0 until array(i).length) { println(array(i)(j)) } val array1: Array[Array[String]] = Array.ofDim[String](2, 3) for (i <- array1.indices; j <- array1(i).indices) { print(array1(i)(j) + "\t") if (j == array1(i).length - 1) println() } array.foreach( (line) => { line.foreach(println(_)) } ) array.foreach( _.foreach(println) ) } }
7.3 列表List
-
不可变列表
package chapter07 object Test04_ImmutableList { def main(args: Array[String]): Unit = { // 列表 // 1. 创建List,不能用class创建,只能用伴生对象创建 // sealed abstract class List 中sealed表示List类的子类只能在本文件创建 val list1 = List(1, 2, 3, 4, 5, 6) println(list1) // 2. 访问和遍历元素 println(list1(0)) // 此处不能像Array更改某个位置的值 // list1(0) = 10 error // list1.foreach(println) // 3. 添加元素 // 头部添加 10 +: list1 val list2: List[Int] = list1.+:(10) // 尾部添加 list1 :+ 19 val list3: List[Int] = list1.:+(19) println(list2) println(list3) // 双冒号主要用于创建一个列表 val list4 = list1.::(51) println(list4) println(52 :: list1) // 创建一个列表 val list5 = 32 :: 39 :: Nil // 4. 列表合并 val list6 = list4 :: list5 // List(List(51, 1, 2, 3, 4, 5, 6), 32, 39) println(list6) // 3冒号用于列表拼接,扁平化合并 val list7 = list4 ::: list5 // List(51, 1, 2, 3, 4, 5, 6, 32, 39) println(list7) // 等价,列表拼接,扁平化合并 println(list4 ++ list5) } }
-
可变列表
package chapter07 import scala.collection.mutable.ListBuffer object Test05_MutableListBuffer { def main(args: Array[String]): Unit = { // 1. 创建可变列表 val list1 = new ListBuffer[Int]() val list2 = ListBuffer(12, 13, 29) println(list1) println(list2) // 2. 添加元素,使用方法函数 list1.append(1, 2, 3) list1.insert(1, 19, 22) list2.prepend(34, 2) println(list1) println(list2) // 3. 合并list ++ 会返回新的对象,++= 会更改 val list3 = list1 ++ list2 println(list3) list1 ++= list2 println(list1) // 4. 修改元素 list2(2) = 3333 list2.update(0, 99) println(list2) // 5. 删除元素 // 指定位置删除 list2.remove(2) // 指定元素删除 list2 -= 29 println(list2) } }
7.4 Set 集合
-
不可变Set
package chapter07 object Test06_ImmutableSet { def main(args: Array[String]): Unit = { // 1. 创建Set,new Set()不能创建,Set为特征,因此只能用伴生对象创建 val set1 = Set(1, 2, 3, 34, 2, 3) println(set1) // 2. 添加元素 println("=========2. 添加元素============") val set2 = set1 + 10 + 10 + 20 + 20 + 30 println(set2) // 3. 合并set println("=========3. 合并set============") val set3 = Set(1, 2, 3, 4, 9, 10) val set4 = set2 ++ set3 println(set4) // 4. 删除元素 println("=========4. 删除元素============") val set5 = set4 - 30 println(set4) println(set5) } }
-
可变Set
package chapter07 import scala.collection.mutable object Test07_MutableSet { def main(args: Array[String]): Unit = { // 1. 创建可变set val set1: mutable.Set[Int] = mutable.Set(1, 2, 3, 4, 10) println(set1) // 2. 添加元素,使用方法名 println("============2. 添加元素============") val flag1 = set1.add(12) println(set1) println(flag1) val flag2 = set1.add(12) println(set1) println(flag2) // 3. 删除元素 println("============3. 删除元素============") set1.remove(12) println(set1) // 4. 合并两个set ++= println("============4. 合并两个set============") val set3 = mutable.Set(111, 222, 3, 4, 101) println(set1) println(set3) set1 ++= set3 println(set1) println(set3) } }
7.5 Map 集合
-
不可变Map
package chapter07 object Test08_ImmutableMap { def main(args: Array[String]): Unit = { // 1. 创建Map val map1: Map[String, Int] = Map[String, Int]("scc" -> 18, "hello" -> 10) println(map1) println(map1.getClass) val map0 = Map[String, Int]() println(map0) println(map0.getClass) // 2. 遍历元素 map1.foreach(println(_)) map1.foreach(kv => println(s"key is ${kv._1}, value is ${kv._2}")) // 3. 取map中所有key或者value /** * println(s"$key-->${map1.get(key)}") * scc-->Some(18) * hello-->Some(10) */ for (key <- map1.keys) { println(s"$key-->${map1.get(key)}") println(s"$key-->${map1.getOrElse(key, 0)}") } for (value <- map1.values) { println(value) } } }
-
可变Map
package chapter07 import scala.collection.mutable object Test09_MutableMap { def main(args: Array[String]): Unit = { // 1. 创建Map val map1 = mutable.Map[String, Int]("scc" -> 18, "hello" -> 10) println(map1) println(map1.getClass) // 2. 添加元素 map1.put("zyy", 19) println(map1) map1 += (("a", 20), ("b", 22)) println(map1) // 3. 删除元素 map1.remove("zyy") map1 -= "d" println(map1) // 4. 修改元素 map1.update("a", 209) println(map1) // 5. 合并两个Map val map2 = mutable.Map[String, Int]("x" -> 108, "hello" -> 11) println(map1) println(map2) map1 ++= map2 println(map1) println(map2) val map3: mutable.Map[String, Int] = map1 ++ map2 // 6. immutable.map 和 mutable.map 互转 val map4: Map[String, Int] = map3.toMap val map5: mutable.Map[String, Int] = collection.mutable.Map(map4.toSeq: _*) } }
7.6 元组
package chapter07
object Test10_Tuple {
def main(args: Array[String]): Unit = {
// 1. 创建元组
val tuple1: (String, Int, Char, Boolean) = ("hello", 100, 'a', true)
println(tuple1)
// 2. 访问数据
println(tuple1._1)
println(tuple1._2)
println(tuple1._3)
println(tuple1._4)
// 索引从0开始,建议使用下划线_
println(tuple1.productElement(1))
// 3. 遍历元组数据
for (ele <- tuple1.productIterator) {
println(ele)
}
// 4. 嵌套元组
val mulTuple = (12, 0.3, "hello", (23, "scala"), 29)
println(mulTuple._1)
println(mulTuple._4._2)
}
}
7.7 集合常用函数
-
通用属性和操作
package chapter07 object Test11_CommonOp { def main(args: Array[String]): Unit = { val list: List[Int] = List(1, 2, 3, 4) val set = Set(1, 2, 3, 4) // 1. 获取集合长度 println(list.length) // 3. 获取集合大小 println(list.size) println(set.size) // 3. 循环遍历 for (elem <- list){ println(elem) } // 4. 迭代器 for (elem <- list.iterator){ println(elem) } val iterator: Iterator[Int] = list.iterator while (iterator.hasNext){ println(iterator.next()) } // 5. 生成字符串 println(list) println(set) println(list.mkString("--")) // 6. 是否包含 println(list.contains(1)) println(list.contains(5)) println(set.contains(2)) } }
-
衍生集合
package chapter07 object Test12_DerivedCollection { def main(args: Array[String]): Unit = { val list1: List[Int] = List(1, 3, 5, 7, 2, 89) val list2: List[Int] = List(3, 7, 2, 45, 4, 8, 19) // 1. 获取集合的头 println("=============1. 获取集合的头=============") println(list1.head) // 2. 获取集合的尾(不是头的尾) println("=============2. 获取集合的尾(不是头的尾)=============") println(list1.tail) // 3. 获取集合的最后一个元素 println("=============3. 获取集合的最后一个元素=============") println(list1.last) // 4. 获取集合初始元素(不包含最后一个) println("=============4. 获取集合初始元素(不包含最后一个)=============") println(list1.init) // 5. 翻转 println("=============5. 翻转=============") println(list1.reverse) // 6. 取前(后)n个元素 println("=============6. 取前(后)n个元素=============") println(list1.take(3)) println(list1.takeRight(4)) // 7. 去掉前(后)n个元素 println("=============7. 去掉前(后)n个元素=============") println(list1.drop(3)) println(list1.dropRight(4)) println("=============以下操作,涉及两个集合操作=============") // 8. 交集 println("=============8. 交集=============") val intersect = list1 intersect list2 println(intersect) // 9. 并集 println("=============9. 并集=============") val union = list1 union list2 println(union) println(list1 ::: list2) // 10. 差集 println("=============10. 差集=============") val diff1: List[Int] = list1.diff(list2) val diff2: List[Int] = list2.diff(list1) println(diff1) println(diff2) // 11. 拉链,取最小集合长度为准 println("=============11. 拉链,取最小集合长度为准=============") println(s"list1: $list1") println(s"list2: $list2") val zip1: List[(Int, Int)] = list1.zip(list2) val zip2: List[(Int, Int)] = list2.zip(list1) println(s"zip1: $zip1") println(s"zip2: $zip2") // 12. 滑窗 println("=============12. 滑窗=============") // List(1, 3, 5, 7, 2, 89) println(list1) /** * List(1) * List(3) * List(5) * List(7) * List(2) * List(89) */ list1.sliding(1).foreach(println) /** * List(1, 3) * List(3, 5) * List(5, 7) * List(7, 2) * List(2, 89) */ list1.sliding(2).foreach(println) /** * List(1, 3) * List(7, 2) */ list1.sliding(2, 3).foreach(println) /** * 窗口无重复数据,又叫滚动滑动窗口 * List(1, 3) * List(5, 7) * List(2, 89) */ list1.sliding(2, 2).foreach(println) } }
-
简单计算函数
package chapter07 object Test13_SimpleOp { def main(args: Array[String]): Unit = { val list: List[Int] = List(5, 1, 8, 2, -3, 4) val list2 = List(("a", 5), ("b", 1), ("c", 8), ("d", 2), ("e", -3), ("f", 4)) // 1. 求和 println(list.sum) val i: Int = list.reduce((a, b) => { a + b }) println(i) // 2. 求积 println(list.product) // 3. 最大值 println(list.max) println(list2.max) println(list2.maxBy(elem => { elem._2 })) println(list2.maxBy(_._2)) // 4. 最小值 println(list.min) // 5. 排序 // 按照第一个位置元素排序 /** * List(-3, 1, 2, 4, 5, 8) * List(8, 5, 4, 2, 1, -3) * List((a,5), (b,1), (c,8), (d,2), (e,-3), (f,4)) * List((f,4), (e,-3), (d,2), (c,8), (b,1), (a,5)) */ println(list.sorted) // 从小到大排序 println(list.sorted(scala.math.Ordering.Int.reverse)) // 从大到小排序 println(list2.sorted) // 从小到大排序 println(list2.sorted(scala.math.Ordering.Tuple2[String, Int].reverse)) // 从大到小排序 // 指定位置元素排序,从大到小 /** * List((c,8), (a,5), (f,4), (d,2), (b,1), (e,-3)) * List((c,8), (a,5), (f,4), (d,2), (b,1), (e,-3)) */ println(list2.sortBy(elem => { elem._2 })(scala.math.Ordering[Int].reverse)) println(list2.sortBy( _._2 )(scala.math.Ordering.Int.reverse)) // 上面方法太麻烦,使用sortWith进行简化 println(list.sortWith(_ < _)) println(list.sortWith(_ > _)) list2.sortWith((a, b) => { a._2 > b._2 }) /** * sorted:适合单集合的升降序 * * sortBy:适合对单个或多个属性的排序,代码量比较少,推荐使用这种 * * sortWith:适合定制化场景比较高的排序规则,比较灵活,也能支持单个或多个属性的排序,但代码量稍多,内部实际是通过java里面的Comparator接口来完成排序的。 * */ } }
-
高级计算函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q6sxYWMa-1687453296535)(assets/image-20230622235948-255wdrz.png)]
package chapter07 object Test14_HighLevelFunction_Map { def main(args: Array[String]): Unit = { /** * List(2, 4, 6, 8) * List(2, 4, 6, 8, 10, 12, 14, 16, 18) * List(List(1, 2, 3), List(4, 5), List(6, 7, 8, 9)) * List(1, 2, 3, 4, 5, 6, 7, 8, 9) * List(Hello, Scala, Hello, World) * List(Hello, Scala, Hello, World) * Map(1 -> List(1, 3, 5, 7, 9), 0 -> List(2, 4, 6, 8)) * Map(2 -> List(2, 5, 8), 1 -> List(1, 4, 7), 0 -> List(3, 6, 9)) * Map(S -> List(Scala), W -> List(World), H -> List(Hello, Hello)) * */ val list = List(1, 2, 3, 4, 5, 6, 7, 8, 9) // 1. 过滤 val evenList: List[Int] = list.filter(_ % 2 == 0) println(evenList) // 2. 转化/映射 map val multiply2: List[Int] = list.map(_ * 2) println(multiply2) // 3. 扁平化 val nestedList: List[List[Int]] = List(List(1, 2, 3), List(4, 5), List(6, 7, 8, 9)) println(nestedList) val flattenList: List[Int] = nestedList.flatten println(flattenList) // 4. 扁平化和映射 flatMap,先map,再flatten // 将一组单词,进行分词,再保存成单词列表 val strings: List[String] = List("Hello Scala", "Hello World") println(strings.map(_.split(" ")).flatten) println(strings.flatMap(_.split(" "))) // 5. 分组,groupBy // 直接分成奇数和偶数两组 println(list.groupBy(_ % 2)) println(list.groupBy(_ % 3)) // 给定一组单词,按照单词的首字母进行分组 val stringList1: List[String] = List("Hello Scala", "Hello World") println(stringList1.flatMap(_.split(" ")).groupBy((elem) => { elem.charAt(0) })) } }
package chapter07 object Test15_HighLevelFunction_Reduce { def main(args: Array[String]): Unit = { val list = List(1, 2, 3, 4) // 1. reduce println(list.reduce(_ + _)) println(list.reduceLeft(_ + _)) println(list.reduceRight(_ + _)) println("===============================") /** * -24 * -24 * 6 */ val list2 = List(3, 4, 5, 8, 10) println(list2.reduce(_ - _)) println(list2.reduceLeft(_ - _)) println(list2.reduceRight(_ - _)) // (3-(4-(5-(8-10)))) println("==============2. fold=================") // 2. fold /** * ==============2. fold================= * 20 * 20 * -5 */ println(list.fold(10)(_ + _)) println(list.foldLeft(10)(_ + _)) println(list2.foldRight(11)(_ - _)) // (3-(4-(5-(8-(10-10))))) } }
-
应用案例-合并Map
package chapter07 import scala.collection.mutable object Test16_MergeMap { def main(args: Array[String]): Unit = { // 遍历map1 val map1 = Map("a" -> 1, "b" -> 3, "c" -> 6) // 更新map2 val map2 = mutable.Map("a" -> 6, "b" -> 2, "c" -> 9, "d" -> 3) println(map1) println(map2) map1.foreach(elem => { val value1 = elem._2 val value2 = map2.getOrElse(elem._1, 0) map2.update(elem._1, value1 + value2) }) println(map2) map1.foldLeft(map2)( (mergedMap, kv) => { val key = kv._1 val value = kv._2 mergedMap.update(key, mergedMap.getOrElse(key, 0) + value) mergedMap }) println(map2) } }
-
队列
-
并行集合