经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Scala » 查看文章
10. Scala数据结构(上)-集合操作
来源:cnblogs  作者:铖歌  时间:2019/5/10 9:03:50  对本文有异议

10.1 数据结构特点 

  10.1.1 Scala集合基本介绍 

      uml => 统一建模语言

      1) Scala同时支持不可变集合和可变集合,不可变集合可以安全的并发访问

      两个主要的包

      不可变集合:scala.collection.immutable

      可变集合:scala.collection.mutable

      2) Scala默认采用不可变集合,对于几乎所有的集合类,Scala都同时提供了可变(mutable)和不可变(immutable)的版本

      3) Scala的集合有三大类:序列Seq(有序的,Linear Seq),集Set,映射Map[key -> value],所有的集合都扩展自Iterable特质,在Scala中集合有可变(mutable)和不可变(immutable)

  10.1.2 可变集合和不可变集合举例 

      1) 不可变集合:Scala不可变集合,就是集合本身不能动态变化(类似Java的数组,是不可以动态增长的)

      2) 可变集合:可变集合,就是这个集合本身可以动态变化(比如:ArrayList,是可以动态增长的)

      3) 使用Java做了一个简单的案例

  1. import java.util.ArrayList;
  2.  
  3. public class JavaCollection {
  4. public static void main(String[] args) {
  5. //不可变集合类似java的数组
  6. int[] nums = new int[3];
  7. nums[2] = 6; //?
  8. nums[2] = 7;
  9. //nums[3] = 8; //?
  10.  
  11. // String[] names = {"bj", "sh"};
  12. // System.out.println(nums + " " + names);
  13. //
  14. // //可变集合举例
  15. ArrayList al = new ArrayList<String>();
  16. al.add("狗蛋");
  17. al.add("铁蛋");
  18. System.out.println(al + " 地址= " + al.hashCode()); //地址
  19. al.add("熊大");
  20. System.out.println(al + " 地址2=" + al.hashCode()); //地址
  21.  
  22. }
  23. }

10.2 不可变集合继承层次一览图

  10.2.1 图

  10.2.2 小结

      1) Set、Map是Java中也有的集合

      2) Seq是Java没有的,我们发现List归属到Seq了,因此这里的List就和Java不是同一个概念了

      3) 前面讲述的for循环有一个1 to 3,就是IndexedSeq下的Vector

      4) String也是属于IndexedSeq

      5) 经典的数据结构比如Queue和Stack被归属到LinearSeq

      6) 注意Scala中的Map体系中有一个SortedMap,说明Scala的Map可以支持排序

      7) IndexSeq和LinearSeq的区别[IndexSeq是通过索引来查找和定位,因此速度快,比如String就是一个索引集合,通过索引即可定位] [LinearSeq是线型的,即有头尾的概念,这种数据结构一般是通过遍历来查找,它的价值在于应用到一些具体的应用场景(电商网站,大数据推荐系统:最近浏览的10个商品)]

10.3 可变集合继承层次一览图

  10.3.1 图

  10.3.2 对上图的说明 

      1) 在可变集合中比不可变集合更丰富

      2) 在Seq集合中,增加了Buffer集合,常用的有ArrayBuffer和ListBuffer

      3) 如果涉及到线程安全问题可以选择使用syn...开头的集合

10.4 数组-定长数组(声明泛型) 

  10.4.1 第一种方式定义数组

      -说明

        这里的数组等同于Java中的数组,中括号的类型就是数组的类型

        val arr = new Array[Int](10)

        arr(1) = 9

      -案例演示

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4. //说明
  5. //1. 创建了一个Array对象,
  6. //2. [Int] 表示泛型,即该数组中,只能存放Int
  7. //3. [Any] 表示 该数组可以存放任意类型
  8. //4. 在没有赋值情况下,各个元素的值 0
  9. //5. arr(3) = 10 表示修改 第4个元素的值
  10. val arr = new Array[Int](4) //底层 int[] arr = new int[4]
  11. println(arr.length) // 4
  12.  
  13. println("arr(0)=" + arr(0)) // 0
  14. //数据的遍历
  15.  
  16. for (i <- arr) {
  17. println(i)
  18. }
  19. println("--------------------")
  20. arr(3) = 10 //
  21. for (i <- arr) {
  22. println(i)
  23. }
  24.  
  25. }
  26. }

  10.4.2 第二种方式定义数组 

      -说明

        在定义数组时,直接赋值

        //使用apply方法创建数组对象

        val arr = Apply(1,2)

      -案例演示

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4. //说明
  5. //1. 使用的是 object Array 的apply
  6. //2. 直接初始化数组,这时因为你给了 整数和 "", 这个数组的泛型就Any
  7. //3. 遍历方式一样
  8. var arr = Array(1, 3, "xx")
  9. arr(1) = "xx"
  10. for (i <- arr) {
  11. println(i)
  12. }
  13.  
  14. //可以使用我们传统的方式遍历,使用下标的方式遍历
  15. for (index <- 0 until arr.length) {
  16. printf("arr02[%d]=%s", index, arr(index) + "\t")
  17. }
  18.  
  19. }
  20. }

10.5 数组-变长数组[声明泛型]  

      -说明

        //定义/声明

        val arr = ArrayBuffer[Int]()

        //追加值/元素

        arr.append(9)

        //重新赋值

        arr(0) = 6

      -案例演示

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4. //创建ArrayBuffer
  5. val arr = ArrayBuffer[Any](3, 2, 5)
  6.  
  7. //访问,查询
  8. //通过下标访问元素
  9. println("arr(1)=" + arr(1)) // arr(1) = 2
  10. //遍历
  11. for (i <- arr) {
  12. println(i)
  13. }
  14. println(arr.length) //3
  15. println("arr.hash=" + arr.hashCode())
  16.  
  17.  
  18. //修改 [修改值,动态增加]
  19. //使用append 追加数据 ,append支持可变参数
  20. //可以理解成java的数组的扩容
  21. arr.append(90.0, 13) // (3,2,5,90.0,13)
  22. println("arr.hash=" + arr.hashCode())
  23.  
  24.  
  25. println("===================")
  26.  
  27.  
  28. arr(1) = 89 //修改 (3,89,5,90.0,13)
  29. println("--------------------------")
  30. for (i <- arr) {
  31. println(i)
  32. }
  33.  
  34. //删除...
  35. //删除,是根据下标来说
  36.  
  37. arr.remove(0) // (89,5,90.0,13)
  38. println("--------删除后的元素遍历---------------")
  39. for (i <- arr) {
  40. println(i)
  41. }
  42. println("最新的长度=" + arr.length) // 4
  43.  
  44. }
  45. }

  10.5.1 变长数组分析小结 

      1) ArrayBuffer是变长数组,类似Java的ArrayList

      2) val arr = ArrayBuffer[Int]() 也是使用apply方法构建对象

      3) def append(elems: A*) { appendAll(elems) } 接收的是可变参数

      4) 每append一次,arr在底层会重新分配空间,进行扩容,arr的内存地址会发生变化,也就成为新的ArrayBuffer

  10.5.2 定长数组与变长数组的转换 

      -说明

        在开发中,我们可能使用对定长数组和变长数组进行转换

          arr1.toBuffer //定长数组转可变数组

          arr2.toArray //可变数组转定长数组

      -注意事项

        arr1.toBuffer 返回结果才是一个可变数组,arr1本身没有变化

        arr2.toArray 返回结果才是一个定长数组,arr2本身没有变化

      -案例演示

  1. import scala.collection.mutable.ArrayBuffer
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6.  
  7. val arr2 = ArrayBuffer[Int]()
  8. // 追加值
  9. arr2.append(1, 2, 3)
  10. println(arr2)
  11.  
  12. //说明
  13. //1. arr2.toArray 调用 arr2的方法 toArray
  14. //2. 将 ArrayBuffer ---> Array
  15. //3. arr2本身没有任何变化
  16. val newArr = arr2.toArray
  17. println(newArr)
  18.  
  19. //说明
  20. //1. newArr.toBuffer 是把 Array->ArrayBuffer
  21. //2. 底层的实现
  22. /*
  23. override def toBuffer[A1 >: A]: mutable.Buffer[A1] = {
  24. val result = new mutable.ArrayBuffer[A1](size)
  25. copyToBuffer(result)
  26. result
  27. }
  28. */
  29. //3. newArr本身没变化
  30. val newArr2 = newArr.toBuffer
  31. newArr2.append(123)
  32. println(newArr2)
  33.  
  34. }
  35. }

  10.5.3 多维数组的定义和使用 

      -说明

        //定义

        val arr = Array.ofDim[Double](3,4)

        //说明:二维数组中有三个一维数组,每个一维数组中有四个元素

        //赋值

        aar(1)(1) = 9.6

      -案例演示

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4. //创建
  5. val arr = Array.ofDim[Int](3, 4)
  6.  
  7. //遍历
  8. for (item <- arr) { //取出二维数组的各个元素(一维数组)
  9. for (item2 <- item) { // 元素(一维数组) 遍历
  10. print(item2 + "\t")
  11. }
  12. println()
  13. }
  14. //指定取出
  15. println(arr(1)(1)) // 0
  16.  
  17. //修改值
  18. arr(1)(1) = 9
  19.  
  20. //遍历
  21. println("=====================")
  22. for (item <- arr) { //取出二维数组的各个元素(一维数组)
  23. for (item2 <- item) { // 元素(一维数组) 遍历
  24. print(item2 + "\t")
  25. }
  26. println()
  27. }
  28.  
  29. //使用传统的下标的方式来进行遍历
  30. println("===================")
  31. for (i <- 0 to arr.length - 1) { //先对
  32. for (j <- 0 to arr(i).length - 1) {
  33. printf("arr[%d][%d]=%d\t", i, j, arr(i)(j))
  34. }
  35. println()
  36.  
  37. }
  38. }
  39. }

10.6 数组-Scala数组与Java的List的互转

  10.6.1 Scala数组转Java的List 

      在开发中,有时需要我们将Scala数组转成Java数组

  10.6.2 案例演示 

  1. import scala.collection.mutable.ArrayBuffer
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6. // Scala集合和Java集合互相转换
  7. val arr = ArrayBuffer("1", "2", "3")
  8. /*
  9. implicit def bufferAsJavaList[A](b : scala.collection.mutable.Buffer[A]) : java.util.List[A] = { /* compiled code */ }
  10. */
  11. import scala.collection.JavaConversions.bufferAsJavaList
  12. //对象 ProcessBuilder , 因为 这里使用到上面的 bufferAsJavaList
  13. val javaArr = new ProcessBuilder(arr) //为什么可以这样使用?
  14. // 这里arrList 就是java中的List
  15. val arrList = javaArr.command()
  16.  
  17. println(arrList) //输出 [1, 2, 3]
  18.  
  19. }
  20. }

  10.6.3 Java的List转Scala数组(mutable.Buffer) 

      -案例演示

  1. //java的List 转成 scala的 ArrayBuffer
  2. //说明
  3. //1. asScalaBuffer 是一个隐式函数
  4. /*
  5. implicit def asScalaBuffer[A](l : java.util.List[A]) : scala.collection.mutable.Buffer[A] = { /* compiled code */ }
  6. */
  7. import scala.collection.JavaConversions.asScalaBuffer
  8. import scala.collection.mutable
  9. // java.util.List ==> Buffer
  10. val scalaArr: mutable.Buffer[String] = arrList
  11. scalaArr.append("jack")
  12. scalaArr.append("tom")
  13. scalaArr.remove(0)
  14. println(scalaArr) // (2,3,jack,tom)

10.7 元组Tuple-元组的基本使用 

  10.7.1 基本介绍 

      元组也是可以理解为一个容器,可以存放各种相同或者不同类型的数据。说得简单点,就是将多个无关的数据封装为一个整体,称为元组。特点灵活,对数据没有过多的约束。注意:元组中最多只能有22个元素

  10.7.2 元组的创建 

      -案例演示

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4.  
  5. //创建
  6. //说明 1. tuple 就是一个 Tuple 类型是 Tuple5
  7. //简单说明: 为了高效的操作元组 , 编译器根据元素的个数不同,对应不同的元组类型 // 分别 Tuple1----Tuple22
  8. val tuple = (1, 2, 3, "hello", 4)
  9. println(tuple)
  10. }
  11. }

      -对案例演示的说明 

        1) tuple的类型是Tuple5类,是Scala特有的类型

        2) tuple的类型取决于tuple后面有多少个元素,有对应关系,比如:4个元素 -> Tuple4

        3) 看一个Tuple5类的定义

  1. final case class Tuple5[+T1, +T2, +T3, +T4, +T5](_1: T1, _2: T2, _3: T3, _4: T4, _5: T5) extends Product5[T1, T2, T3, T4, T5] {
  2. override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + ")"
  3. }

        4) 元组中最多只能有22个元素,即Tuple1 -> Tuple22

10.8 元组Tuple-元组数据的访问 

  10.8.1 基本介绍 

      访问元组中的数据,可以采用顺序号(_顺序号),也可以通过索引(productElement)访问

  10.8.2 应用案例 

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4.  
  5. //访问元组
  6. val t1 = (1, "a", "b", true, 2)
  7. println(t1._1) // 1 //访问元组的第一个元素 ,从 1 开始
  8.  
  9. println(t1.productElement(0)) // 1 // 访问元组的第一个元素,从 0 开始
  10. }
  11. }

10.9 元组Tuple-元组数据的遍历  

      Tuple是一个整体,遍历需要调其迭代器

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4.  
  5. val t1 = (1, "a", "b", true, 2)
  6.  
  7. //遍历元组, 元组的遍历需要使用到迭代器
  8. for (item <- t1.productIterator) {
  9. println("item=" + item)
  10. }
  11. }
  12. }

10.10 列表List-创建List 

  10.10.1 基本介绍 

      Scala中的List和Java List不一样,在Java中List是一个接口,真正存放数据的是ArrayList,而Scala的List可以直接存放数据,就是一个object,默认情况下Scala的List是不可变的,List属于序列Seq

      val List = scala.collection.immutable.List

      object List extends SeqFactory[List]

  10.10.2 创建List的应用案例 

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4. //说明
  5. //1. 在默认情况下 List 是scala.collection.immutable.List,即不可变
  6. //2. 在scala中,List就是不可变的,如需要使用可变的List,则使用ListBuffer
  7. //3. List 在 package object scala 做了 val List = scala.collection.immutable.List
  8. //4. val Nil = scala.collection.immutable.Nil // List()
  9.  
  10. val list01 = List(1, 2, 3, "Hello") //创建时,直接分配元素
  11. println(list01)
  12.  
  13. val list02 = Nil //空集合
  14. println(list02)
  15.  
  16. }
  17. }

  10.10.3 创建List的应用案例小结 

      1) List默认为不可变的集合

      2) List在Scala包对象声明的,因此不需要引入其它包也可以使用

        val List = scala.collection.immutable.List

      3) List中可以放任何数据类型,比如:arr1的类型为List[Any]

      4) 如果希望得到一个空列表,可以使用Nil对象,在Scala包对象声明的,因此不需要引入其它包也可以使用

        val Nil = scala.collection.immutable.Nil

10.11 列表List-访问List元素 

  1. //访问 List 的元素
  2. val value1 = list01(1) // 1 是索引,表示取出第 2 个元素
  3. println("value1=" + value1) // 2

10.12 列表List-元素的追加 

  10.12.1 接本介绍 

      向列表中增加元素,会返回新的列表/集合对象。注意:Scala中List元素的追加形式非常独特,和Java不一样

  10.12.2 方式1-在列表的最后增加数据 

      -案例演示

  10.12.3 方式2-在列表的最前面增加数据

      -案例演示

  1. println("-------------list 追加元素后的效果-----------------")
  2. //通过 :+ 和 +: 给 list 追加元素(本身的集合并没有变化)
  3. var list1 = List(1, 2, 3, "abc")
  4. // :+运算符表示在列表的最后增加数据
  5. val list2 = list1 :+ 4 // (1,2,3,"abc", 4)
  6. println(list1) //list1 没有变化 (1, 2, 3, "abc"),说明 list1 还是不可变
  7. println(list2) //新的列表结果是 [1, 2, 3, "abc", 4]
  8. val list3 = 10 +: list1 // (10,1, 2, 3, "abc")
  9. println("list3=" + list3)

  10.12.4 方式3-在列表的最后增加数据 

      -说明

        1) 符号::表示向集合中 新建集合添加元素

        2) 运算时,集合对象一定要放置在最右边

        3) 运算规则,从右向左

        4) ::: 运算符是将集合中的每一个元素加入到集合中去

      -案例演示

  1. //:: 符号的使用
  2.  
  3. val list4 = List(1, 2, 3, "abc")
  4. //说明 val list5 = 4 :: 5 :: 6 :: list4 :: Nil 步骤
  5. //1. List()
  6. //2. List(List(1, 2, 3, "abc"))
  7. //3. List(6,List(1, 2, 3, "abc"))
  8. //4. List(5,6,List(1, 2, 3, "abc"))
  9. //5. List(4,5,6,List(1, 2, 3, "abc"))
  10. val list5 = 4 :: 5 :: 6 :: list4 :: Nil
  11. println("list5=" + list5)
  12.  
  13. //说明 val list6 = 4 :: 5 :: 6 :: list4 ::: Nil 步骤
  14. //1. List()
  15. //2. List(1, 2, 3, "abc")
  16. //3. List(6,1, 2, 3, "abc")
  17. //4. List(5,6,1, 2, 3, "abc")
  18. //5. List(4,5,6,1, 2, 3, "abc")
  19. val list6 = 4 :: 5 :: 6 :: list4 ::: Nil
  20. println("list6=" + list6)

10.13 ListBuffer 

  10.13.1 基本介绍 

      ListBuffer是可变的list集合,可以添加,删除元素,ListBuffer属于序列

      //追一下继承关系即可

      Seq var listBuffer = ListBuffer(1,2)

  10.13.2 案例演示 

  1. import scala.collection.mutable.ListBuffer
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6. //创建ListBuffer
  7. val lst0 = ListBuffer[Int](1, 2, 3)
  8.  
  9. //如何访问
  10. println("lst0(2)=" + lst0(2)) // 输出 lst0(2)= 3
  11. for (item <- lst0) { // 遍历,是有序
  12. println("item=" + item)
  13. }
  14.  
  15. //动态的增加元素,lst1就会变化, 增加一个一个的元素
  16. val lst1 = new ListBuffer[Int] //空的ListBuffer
  17. lst1 += 4 // lst1 (4)
  18. lst1.append(5) // list1(4,5)
  19.  
  20. //
  21. lst0 ++= lst1 // lst0 (1, 2, 3,4,5)
  22.  
  23. println("lst0=" + lst0)
  24.  
  25.  
  26. val lst2 = lst0 ++ lst1 // lst2(1, 2, 3,4,5,4,5)
  27. println("lst2=" + lst2)
  28.  
  29. val lst3 = lst0 :+ 5 // lst0 不变 lst3(1, 2, 3,4,5,5)
  30. println("lst3=" + lst3)
  31.  
  32.  
  33. println("=====删除=======")
  34. println("lst1=" + lst1)
  35. lst1.remove(1) // 表示将下标为1的元素删除
  36. for (item <- lst1) {
  37. println("item=" + item) //4
  38. }
  39.  
  40. }
  41. }

10.14 队列Queue-基本介绍 

  10.14.1 队列的说明 

      1) 队列是一个有序列表,在底层可以用数组或是链表来实现

      2) 其输入和输出要遵循先入先出的原则。即:现存入队列的数据,要先取出。后存入的要后取

      3) 在Scala中,由设计者直接给我们提供队列类型Queue使用

      4) 在Scala中,有scala.collection.mutable.Queue 和 scala.collection.immutable.Queue,一般来说,在开发中通常使用可变集合中的队列

10.15 队列Queue-队列的创建 

  1. import scala.collection.mutable
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6. //创建队列
  7. val q1 = new mutable.Queue[Int]
  8. println(q1)
  9.  
  10. }
  11. }

10.16 队列Queue-队列元素的追加数据 

  1. import scala.collection.mutable
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6. //创建队列
  7. val q1 = new mutable.Queue[Int]
  8.  
  9. //给队列增加元素
  10. q1 += 9 // (9)
  11. println("q1=" + q1) // (9)
  12. q1 ++= List(4,5,7) // 默认值直接加在队列后面
  13. println("q1=" + q1) //(9,4,5,7)
  14. //q1 += List(10,0) // 表示将 List(10,0) 作为一个元素加入到队列中
  15.  
  16. }
  17. }

10.17 队列Queue-删除和加入队列元素 

      在队列中,严格地遵守,入队列的数据,放在队尾,出队列的数据是从队列头部取出

  1. //dequeue 从队列的头部取出元素 q1 本身会变
  2. val queueElement = q1.dequeue()
  3. println("queueElement=" + queueElement + "q1="+q1)
  4. //enQueue 入队列,默认是从队列的尾部加入.
  5. q1.enqueue(96,101,201,666)
  6. println("q1=" + q1) // Queue(4, 5, 7, 96,101,201,666)

10.18 队列Queue-返回队列的元素 

  1. //队列 Queue-返回队列的元素
  2. //1. 获取队列的第一个元素
  3. println(q1.head) // 4, 对 q1 没有任何影响
  4. //2. 获取队列的最后一个元素
  5. println(q1.last) // 666, 对 q1 没有任何影响
  6. //3. 取出队尾的数据 ,即:返回除了第一个以外剩余的元素,可以级联使用
  7. println(q1.tail) // (5, 7, 96,101,201,666)
  8. println(q1.tail.tail.tail.tail) // (101,201,666)

10.19 映射Map-基本介绍

  10.19.1 Java中Map回顾  

      HashMap是一个散列表(数组+链表),它存储的内容是键值对(key-value)映射,Java中的HashMap是无序的,key不能重复

  10.19.2 案例演示 

  1. import java.util.HashMap;
  2.  
  3. public class JavaHashMap {
  4. public static void main(String[] args) {
  5.  
  6. HashMap<String,Integer> hm = new HashMap();
  7. hm.put("no1", 100);
  8. hm.put("no2", 200);
  9. hm.put("no3", 300);
  10. hm.put("no4", 400);
  11. hm.put("no1", 500); //更新
  12.  
  13. System.out.println(hm);//无序的
  14. System.out.println(hm.get("no2"));
  15.  
  16. }
  17. }

  10.19.3 Scala中的Map介绍 

      1) Scala中的Map和Java类似,也是一个散列表,它存储的内容也是键值对(key-value)映射,Scala中不可变的Map是有序的,可变的Map是无序的

      2) Scala中,有可变Map(scala.collection.mutable.Map)和不可变Map(scala.collection.immutable.Map)

10.20 映射Map-构建Map 

  10.20.1 方式1-构造不可变映射 

      Scala中的不可变Map是有序的,构建Map中的元素底层是Tuple2类型

      案例演示

  1. object boke_demo01 {
  2.  
  3. def main(args: Array[String]): Unit = {
  4.  
  5. //方式1-构造不可变映射
  6. //1.默认Map是 immutable.Map
  7. //2.key-value 类型支持Any
  8. //3.在Map的底层,每对key-value是Tuple2
  9. //4.从输出的结果看到,输出顺序和声明顺序一致
  10. val map1 = Map("Alice" -> 19, "Tom" -> 20, "Jack" -> 21)
  11. println(map1)
  12. }
  13. }

  10.20.2 方式2-构造可变映射 

  1. //方式2-构造可变映射
  2. //1.从输出的结果看到,可变的map输出顺序和声明顺序不一致
  3. val map2 = mutable.Map("Alice" -> 19, "Tom" -> 20, "Jack" -> 21)
  4. println(map2)

  10.20.3 方式3-创建空的映射 

  1. val map3 = new scala.collection.mutable.HashMap[String, Int]
  2. println(map3)

  10.20.4 方式4-对偶元组 

      -说明

        即创建包含键值对的二元组,和第一种方式等价,只是形式上不同而已

        对偶元组就是只含有两个数据的元组

      -案例演示

  1. //方式 4-对偶元组
  2. val map4 = mutable.Map(("Alice" , 19), ("Tom" , 20), ("Jack" , 21))
  3. println("map4=" + map4)

10.21 映射Map-取值 

  10.21.1 方式1-使用map(key) 

  1. val value1 = map2("Alice")
  2. println(value1)

       -说明

        1) 如果key存在,则返回对应的值

        2) 如果key不存在,则抛出异常[java.util.NoSuchElementException]

        3) 在Java中,如果key不存在则返回null

        4) 案例演示

  1. //方式 1-使用 map(key)
  2. println(map4("Alice")) // 19
  3. // 抛出异常(java.util.NoSuchElementException: key not found:)
  4. //println(map4("Alice~"))

10.21.2 方式2-使用contains方法检查是否存在key 

  1. // 返回 Boolean
  2. // 1.如果 key 存在,则返回 true
  3. // 2.如果 key 不存在,则返回 false
  4. map4.contains("T")

      -说明 

        使用contains先判断再取值,可以防止异常,并加入相应的处理逻辑

      -案例演示

  1. //方式 2-使用 contains 方法检查是否存在 key
  2. if (map4.contains("Alice")) {
  3. println("key 存在,值=" + map4("Alice"))
  4. } else {
  5. println("key 不存在:)")
  6. }

  10.21.3 方式3-使用map.get(key).get取值 

      通过 映射.get(键) 这样的调用返回一个Option对象,要么是Some,要么是None

      -说明

        1) map.get 方法会将数据进行包装

        2) 如果map.get(key) 如果key存在,返回some,如果key不存在,则返回None

        3) 如果 map.get(key).get 如果key存在,则返回key对应的值,否则,抛出异常java.util.NoSuchElementException: None.get

      -案例演示

  1. //方式 3-使用 map.get(key).get 取值
  2. //1. 如果 key 存在 map.get(key) 就会返回 Some(值) ,然后 Some(值).get 就可以取出
  3. //2. 如果 key 不存在 map.get(key) 就会返回 None
  4. println(map4.get("Alice").get)
  5. //println(map4.get("Alice~").get) // 抛出异常

  10.21.4 方式4-使用map.getOrElse()取值 

      -getOrElse方法:def getOrElse[V1 >: V](key: K, default :=> V1)

      -说明

        1) 如果key存在,返回key对应的值

        2) 如果key不存在,返回默认值。在Java中底层有很多类似的操作

        3) 案例演示

  1. //方式 4-使用 map4.getOrElse()取值
  2. println(map4.getOrElse("Alice~~~","默认的值:爱丽丝"))

  10.21.5 如何选择取值的方式 

      1) 如果我们确定map有这个key,则应当使用map(key),速度快

      2) 如果我们不确定map是否有这个key,而且有不同的业务逻辑,使用map.contains(),先判断再加入逻辑

      3) 如果只是简单的希望得到一个值,使用map.getOrElse("ip","127.0.0.1")

10.22 映射Map-对map修改、添加和删除 

  10.22.1 更新map的元素  

      -案例演示

  1. val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
  2. map5("Alice") = 20 //更新
  3. println("map5=" + map5)

      -小结

        1) map是可变的,才能修改,否则报错

        2) 如果key存在:则修改对应的值,key不存在,等价于添加一个key-value

  10.22.2 添加map元素  

      -方式1-增加单个元素

  1. val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
  2. map5 += ("史瑞克" -> 27) //增加
  3. println("map5=" + map5)

       -方式2-增加多个元素

  1. val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
  2. map5 += ("史瑞克" -> 27, "灭霸" -> 100)
  3. println("map5=" + map5)

       -说明:当增加一个key-value,如果key存在就是更新,如果不存在就是添加

  10.22.3 删除map元素 

      -案例演示

  1. val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
  2. map5 += ("史瑞克" -> 27, "灭霸" -> 100)
  3. map5 -= ("Alice","Tom","Ja")
  4. println("map5=" + map5)

      -说明

        1) “Alice”,“Tom”就是要删除的key,可以写多个

        2) 如果key存在,就删除,如果key不存在,也不会报错

10.23 映射Map-对map遍历 

      对map的元素(元组Tuple2对象)进行遍历的方式很多,具体如下:

  1. import scala.collection.mutable
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6.  
  7. val map1 = mutable.Map( ("A", 1), ("B", 2), ("C", 3) )
  8. for ((k, v) <- map1) println(k + " is mapped to " + v)
  9. for (v <- map1.keys) println(v)
  10. for (v <- map1.values) println(v)
  11. for (v <- map1) println(v)
  12. }
  13. }

      -说明

        1) 每遍历一次,返回的元素是Tuple2

        2) 取出的时候,可以按照元组的方式来取

      -案例演示

  1. import scala.collection.mutable
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6.  
  7. //map 的遍历
  8. val map6 = mutable.Map(("A", 1), ("B", 2), ("C", 3))
  9. println("----(k, v) <- map6--------")
  10. for ((k, v) <- map6) println(k + " is mapped to " + v)
  11.  
  12. println("----v <- map6.keys--------")
  13. for (v <- map6.keys) println(v)
  14.  
  15. println("----v <- map6.values--------")
  16. for (v <- map6.values) println(v)
  17.  
  18. //这样取出方式 v 类型是 Tuple2
  19. println("----v <- map6--------")
  20. for (v <- map6) println(v + " key =" + v._1 + " val=" + v._2)
  21. }
  22. }

10.24 集Set-基本介绍 

      集是不重复元素的结合,集不保留顺序,默认是以哈希集实现

  10.24.1 Java中Set的回顾 

      Java中,HashSet是实现Set<E>接口的一个实体类,数据是以哈希表的形式存放的,里面不能包含重复数据。Set接口是一种不包含重复元素的collection,HashSet中的数据也是没有顺序的

  10.24.2 案例演示 

  1. import java.util.HashSet;
  2.  
  3. public class JavaHashSet {
  4. public static void main(String[] args) {
  5. //java中的Set的元素 没有顺序,不能重复
  6. HashSet hs = new HashSet<String>();
  7. hs.add("Jack");
  8. hs.add("Tom");
  9. hs.add("Alice");
  10. hs.add("史瑞克");
  11. System.out.println(hs);
  12.  
  13. }
  14. }

      默认情况下,Scala使用的是不可变集合,如果想要使用可变集合,需要引用scala.collection.mutable.Set包

10.25 集Set-创建

  1. import scala.collection.mutable
  2.  
  3. object boke_demo01 {
  4.  
  5. def main(args: Array[String]): Unit = {
  6.  
  7. val set = Set(1, 2, 3) //不可变
  8. println(set)
  9.  
  10. val set2 = mutable.Set(1, 2, "hello") //可以变
  11. println("set2" + set2)
  12. }
  13. }

10.26 集Set-可变集合的元素添加和删除 

  10.26.1 可变集合的元素添加 

  1. mutableSet.add(4) //方式 1
  2. mutableSet += 6 //方式 2
  3. mutableSet.+=(5) //方式 3

      -说明:如果添加的对象已经存在,则不会重复添加,也不会报错 

  10.26.2 可变集合的元素删除 

  1. val set3 = mutable.Set(1,2,3,"abc")
  2. set3 -= 2 // 操作符形式
  3. set3.remove("abc") // 方法的形式,scala 的 Set 可以直接删除值
  4. println(set3)
  5. //说明:如果删除的对象不存在,则不生效,也不会报错

  10.26.3 Set集合的遍历操作

  1. val set4 = mutable.Set(1, 2, 3, "abc")
  2. for (x <- set4) {
  3. println(x)
  4. }

10.27 集Set-更多操作 

 

   

原文链接:http://www.cnblogs.com/zhanghuicheng/p/10817519.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号