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 做了一个简单的案例
- import java.util.ArrayList;
- public class JavaCollection {
- public static void main(String[] args) {
- // 不可变集合类似 java 的数组
- int[] nums = new int[3];
- nums[2] = 6; //?
- nums[2] = 7;
- //nums[3] = 8; //?
- // String[] names = {"bj", "sh"};
- // System.out.println(nums + " " + names);
- //
- // // 可变集合举例
- ArrayList al = new ArrayList<String>();
- al.add("狗蛋");
- al.add("铁蛋");
- System.out.println(al + "地址 =" + al.hashCode()); // 地址
- al.add("熊大");
- System.out.println(al + "地址 2=" + al.hashCode()); // 地址
- }
- }
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
- 案例演示
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 说明
- //1. 创建了一个 Array 对象,
- //2. [Int] 表示泛型, 即该数组中, 只能存放 Int
- //3. [Any] 表示 该数组可以存放任意类型
- //4. 在没有赋值情况下, 各个元素的值 0
- //5. arr(3) = 10 表示修改 第 4 个元素的值
- val arr = new Array[Int](4) // 底层 int[] arr = new int[4]
- println(arr.length) // 4
- println("arr(0)=" + arr(0)) // 0
- // 数据的遍历
- for (i <- arr) {
- println(i)
- }
- println("--------------------")
- arr(3) = 10 //
- for (i <- arr) {
- println(i)
- }
- }
- }
10.4.2 第二种方式定义数组
- 说明
在定义数组时, 直接赋值
- // 使用 apply 方法创建数组对象
- val arr = Apply(1,2)
- 案例演示
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 说明
- //1. 使用的是 object Array 的 apply
- //2. 直接初始化数组, 这时因为你给了 整数和 "", 这个数组的泛型就 Any
- //3. 遍历方式一样
- var arr = Array(1, 3, "xx")
- arr(1) = "xx"
- for (i <- arr) {
- println(i)
- }
- // 可以使用我们传统的方式遍历, 使用下标的方式遍历
- for (index <- 0 until arr.length) {
- printf("arr02[%d]=%s", index, arr(index) + "\t")
- }
- }
- }
10.5 数组 - 变长数组[声明泛型]
- 说明
- // 定义 / 声明
- val arr = ArrayBuffer[Int]()
- // 追加值 / 元素
- arr.append(9)
- // 重新赋值
- arr(0) = 6
- 案例演示
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 创建 ArrayBuffer
- val arr = ArrayBuffer[Any](3, 2, 5)
- // 访问, 查询
- // 通过下标访问元素
- println("arr(1)=" + arr(1)) // arr(1) = 2
- // 遍历
- for (i <- arr) {
- println(i)
- }
- println(arr.length) //3
- println("arr.hash=" + arr.hashCode())
- // 修改 [修改值, 动态增加]
- // 使用 append 追加数据 ,append 支持可变参数
- // 可以理解成 java 的数组的扩容
- arr.append(90.0, 13) // (3,2,5,90.0,13)
- println("arr.hash=" + arr.hashCode())
- println("===================")
- arr(1) = 89 // 修改 (3,89,5,90.0,13)
- println("--------------------------")
- for (i <- arr) {
- println(i)
- }
- // 删除...
- // 删除, 是根据下标来说
- arr.remove(0) // (89,5,90.0,13)
- println("-------- 删除后的元素遍历 ---------------")
- for (i <- arr) {
- println(i)
- }
- println("最新的长度 =" + arr.length) // 4
- }
- }
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 本身没有变化
- 案例演示
- import scala.collection.mutable.ArrayBuffer
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- val arr2 = ArrayBuffer[Int]()
- // 追加值
- arr2.append(1, 2, 3)
- println(arr2)
- // 说明
- //1. arr2.toArray 调用 arr2 的方法 toArray
- //2. 将 ArrayBuffer ---> Array
- //3. arr2 本身没有任何变化
- val newArr = arr2.toArray
- println(newArr)
- // 说明
- //1. newArr.toBuffer 是把 Array->ArrayBuffer
- //2. 底层的实现
- /*
- override def toBuffer[A1>: A]: mutable.Buffer[A1] = {
- val result = new mutable.ArrayBuffer[A1](size)
- copyToBuffer(result)
- result
- }
- */
- //3. newArr 本身没变化
- val newArr2 = newArr.toBuffer
- newArr2.append(123)
- println(newArr2)
- }
- }
10.5.3 多维数组的定义和使用
- 说明
- // 定义
- val arr = Array.ofDim[Double](3,4)
- // 说明: 二维数组中有三个一维数组, 每个一维数组中有四个元素
- // 赋值
- aar(1)(1) = 9.6
- 案例演示
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 创建
- val arr = Array.ofDim[Int](3, 4)
- // 遍历
- for (item <- arr) { // 取出二维数组的各个元素(一维数组)
- for (item2 <- item) { // 元素(一维数组) 遍历
- print(item2 + "\t")
- }
- println()
- }
- // 指定取出
- println(arr(1)(1)) // 0
- // 修改值
- arr(1)(1) = 9
- // 遍历
- println("=====================")
- for (item <- arr) { // 取出二维数组的各个元素(一维数组)
- for (item2 <- item) { // 元素(一维数组) 遍历
- print(item2 + "\t")
- }
- println()
- }
- // 使用传统的下标的方式来进行遍历
- println("===================")
- for (i <- 0 to arr.length - 1) { // 先对
- for (j <- 0 to arr(i).length - 1) {
- printf("arr[%d][%d]=%d\t", i, j, arr(i)(j))
- }
- println()
- }
- }
- }
10.6 数组 - Scala 数组与 Java 的 List 的互转
10.6.1 Scala 数组转 Java 的 List
在开发中, 有时需要我们将 Scala 数组转成 Java 数组
10.6.2 案例演示
- import scala.collection.mutable.ArrayBuffer
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // Scala 集合和 Java 集合互相转换
- val arr = ArrayBuffer("1", "2", "3")
- /*
- implicit def bufferAsJavaList[A](b : scala.collection.mutable.Buffer[A]) : java.util.List[A] = { /* compiled code */ }
- */
- import scala.collection.JavaConversions.bufferAsJavaList
- // 对象 ProcessBuilder , 因为 这里使用到上面的 bufferAsJavaList
- val javaArr = new ProcessBuilder(arr) // 为什么可以这样使用?
- // 这里 arrList 就是 java 中的 List
- val arrList = javaArr.command()
- println(arrList) // 输出 [1, 2, 3]
- }
- }
10.6.3 Java 的 List 转 Scala 数组(mutable.Buffer)
- 案例演示
- //java 的 List 转成 scala 的 ArrayBuffer
- // 说明
- //1. asScalaBuffer 是一个隐式函数
- /*
- implicit def asScalaBuffer[A](l : java.util.List[A]) : scala.collection.mutable.Buffer[A] = { /* compiled code */ }
- */
- import scala.collection.JavaConversions.asScalaBuffer
- import scala.collection.mutable
- // java.util.List ==> Buffer
- val scalaArr: mutable.Buffer[String] = arrList
- scalaArr.append("jack")
- scalaArr.append("tom")
- scalaArr.remove(0)
- println(scalaArr) // (2,3,jack,tom)
10.7 元组 Tuple - 元组的基本使用
10.7.1 基本介绍
元组也是可以理解为一个容器, 可以存放各种相同或者不同类型的数据. 说得简单点, 就是将多个无关的数据封装为一个整体, 称为元组. 特点灵活, 对数据没有过多的约束. 注意: 元组中最多只能有 22 个元素
10.7.2 元组的创建
- 案例演示
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 创建
- // 说明 1. tuple 就是一个 Tuple 类型是 Tuple5
- // 简单说明: 为了高效的操作元组 , 编译器根据元素的个数不同, 对应不同的元组类型 // 分别 Tuple1----Tuple22
- val tuple = (1, 2, 3, "hello", 4)
- println(tuple)
- }
- }
- 对案例演示的说明
1) tuple 的类型是 Tuple5 类, 是 Scala 特有的类型
2) tuple 的类型取决于 tuple 后面有多少个元素, 有对应关系, 比如: 4 个元素 -> Tuple4
3) 看一个 Tuple5 类的定义
- 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] {
- override def toString() = "(" + _1 + "," + _2 + "," + _3 + "," + _4 + "," + _5 + ")"
- }
4) 元组中最多只能有 22 个元素, 即 Tuple1 -> Tuple22
10.8 元组 Tuple - 元组数据的访问
10.8.1 基本介绍
访问元组中的数据, 可以采用顺序号 (_顺序号), 也可以通过索引(productElement) 访问
10.8.2 应用案例
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 访问元组
- val t1 = (1, "a", "b", true, 2)
- println(t1._1) // 1 // 访问元组的第一个元素 , 从 1 开始
- println(t1.productElement(0)) // 1 // 访问元组的第一个元素, 从 0 开始
- }
- }
10.9 元组 Tuple - 元组数据的遍历
Tuple 是一个整体, 遍历需要调其迭代器
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- val t1 = (1, "a", "b", true, 2)
- // 遍历元组, 元组的遍历需要使用到迭代器
- for (item <- t1.productIterator) {
- println("item=" + item)
- }
- }
- }
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 的应用案例
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 说明
- //1. 在默认情况下 List 是 scala.collection.immutable.List, 即不可变
- //2. 在 scala 中, List 就是不可变的, 如需要使用可变的 List, 则使用 ListBuffer
- //3. List 在 package object scala 做了 val List = scala.collection.immutable.List
- //4. val Nil = scala.collection.immutable.Nil // List()
- val list01 = List(1, 2, 3, "Hello") // 创建时, 直接分配元素
- println(list01)
- val list02 = Nil // 空集合
- println(list02)
- }
- }
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 元素
- // 访问 List 的元素
- val value1 = list01(1) // 1 是索引, 表示取出第 2 个元素
- println("value1=" + value1) // 2
10.12 列表 List - 元素的追加
10.12.1 接本介绍
向列表中增加元素, 会返回新的列表 / 集合对象. 注意: Scala 中 List 元素的追加形式非常独特, 和 Java 不一样
10.12.2 方式 1 - 在列表的最后增加数据
- 案例演示
10.12.3 方式 2 - 在列表的最前面增加数据
- 案例演示
- println("-------------list 追加元素后的效果 -----------------")
- // 通过 :+ 和 +: 给 list 追加元素(本身的集合并没有变化)
- var list1 = List(1, 2, 3, "abc")
- // :+ 运算符表示在列表的最后增加数据
- val list2 = list1 :+ 4 // (1,2,3,"abc", 4)
- println(list1) //list1 没有变化 (1, 2, 3, "abc"), 说明 list1 还是不可变
- println(list2) // 新的列表结果是 [1, 2, 3, "abc", 4]
- val list3 = 10 +: list1 // (10,1, 2, 3, "abc")
- println("list3=" + list3)
10.12.4 方式 3 - 在列表的最后增加数据
- 说明
1) 符号:: 表示向集合中 新建集合添加元素
2) 运算时, 集合对象一定要放置在最右边
3) 运算规则, 从右向左
4) ::: 运算符是将集合中的每一个元素加入到集合中去
- 案例演示
- //:: 符号的使用
- val list4 = List(1, 2, 3, "abc")
- // 说明 val list5 = 4 :: 5 :: 6 :: list4 :: Nil 步骤
- //1. List()
- //2. List(List(1, 2, 3, "abc"))
- //3. List(6,List(1, 2, 3, "abc"))
- //4. List(5,6,List(1, 2, 3, "abc"))
- //5. List(4,5,6,List(1, 2, 3, "abc"))
- val list5 = 4 :: 5 :: 6 :: list4 :: Nil
- println("list5=" + list5)
- // 说明 val list6 = 4 :: 5 :: 6 :: list4 ::: Nil 步骤
- //1. List()
- //2. List(1, 2, 3, "abc")
- //3. List(6,1, 2, 3, "abc")
- //4. List(5,6,1, 2, 3, "abc")
- //5. List(4,5,6,1, 2, 3, "abc")
- val list6 = 4 :: 5 :: 6 :: list4 ::: Nil
- println("list6=" + list6)
- 10.13 ListBuffer
10.13.1 基本介绍
ListBuffer 是可变的 list 集合, 可以添加, 删除元素, ListBuffer 属于序列
- // 追一下继承关系即可
- Seq var listBuffer = ListBuffer(1,2)
10.13.2 案例演示
- import scala.collection.mutable.ListBuffer
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 创建 ListBuffer
- val lst0 = ListBuffer[Int](1, 2, 3)
- // 如何访问
- println("lst0(2)=" + lst0(2)) // 输出 lst0(2)= 3
- for (item <- lst0) { // 遍历, 是有序
- println("item=" + item)
- }
- // 动态的增加元素, lst1 就会变化, 增加一个一个的元素
- val lst1 = new ListBuffer[Int] // 空的 ListBuffer
- lst1 += 4 // lst1 (4)
- lst1.append(5) // list1(4,5)
- //
- lst0 ++= lst1 // lst0 (1, 2, 3,4,5)
- println("lst0=" + lst0)
- val lst2 = lst0 ++ lst1 // lst2(1, 2, 3,4,5,4,5)
- println("lst2=" + lst2)
- val lst3 = lst0 :+ 5 // lst0 不变 lst3(1, 2, 3,4,5,5)
- println("lst3=" + lst3)
- println("===== 删除 =======")
- println("lst1=" + lst1)
- lst1.remove(1) // 表示将下标为 1 的元素删除
- for (item <- lst1) {
- println("item=" + item) //4
- }
- }
- }
10.14 队列 Queue - 基本介绍
10.14.1 队列的说明
1) 队列是一个有序列表, 在底层可以用数组或是链表来实现
2) 其输入和输出要遵循先入先出的原则. 即: 现存入队列的数据, 要先取出. 后存入的要后取
3) 在 Scala 中, 由设计者直接给我们提供队列类型 Queue 使用
4) 在 Scala 中, 有 scala.collection.mutable.Queue 和 scala.collection.immutable.Queue, 一般来说, 在开发中通常使用可变集合中的队列
10.15 队列 Queue - 队列的创建
- import scala.collection.mutable
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 创建队列
- val q1 = new mutable.Queue[Int]
- println(q1)
- }
- }
10.16 队列 Queue - 队列元素的追加数据
- import scala.collection.mutable
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 创建队列
- val q1 = new mutable.Queue[Int]
- // 给队列增加元素
- q1 += 9 // (9)
- println("q1=" + q1) // (9)
- q1 ++= List(4,5,7) // 默认值直接加在队列后面
- println("q1=" + q1) //(9,4,5,7)
- //q1 += List(10,0) // 表示将 List(10,0) 作为一个元素加入到队列中
- }
- }
10.17 队列 Queue - 删除和加入队列元素
在队列中, 严格地遵守, 入队列的数据, 放在队尾, 出队列的数据是从队列头部取出
- //dequeue 从队列的头部取出元素 q1 本身会变
- val queueElement = q1.dequeue()
- println("queueElement=" + queueElement + "q1="+q1)
- //enQueue 入队列, 默认是从队列的尾部加入.
- q1.enqueue(96,101,201,666)
- println("q1=" + q1) // Queue(4, 5, 7, 96,101,201,666)
10.18 队列 Queue - 返回队列的元素
- // 队列 Queue - 返回队列的元素
- //1. 获取队列的第一个元素
- println(q1.head) // 4, 对 q1 没有任何影响
- //2. 获取队列的最后一个元素
- println(q1.last) // 666, 对 q1 没有任何影响
- //3. 取出队尾的数据 , 即: 返回除了第一个以外剩余的元素, 可以级联使用
- println(q1.tail) // (5, 7, 96,101,201,666)
- 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 案例演示
- import java.util.HashMap;
- public class JavaHashMap {
- public static void main(String[] args) {
- HashMap<String,Integer> hm = new HashMap();
- hm.put("no1", 100);
- hm.put("no2", 200);
- hm.put("no3", 300);
- hm.put("no4", 400);
- hm.put("no1", 500); // 更新
- System.out.println(hm);// 无序的
- System.out.println(hm.get("no2"));
- }
- }
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 类型
案例演示
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- // 方式 1 - 构造不可变映射
- //1. 默认 Map 是 immutable.Map
- //2.key-value 类型支持 Any
- //3. 在 Map 的底层, 每对 key-value 是 Tuple2
- //4. 从输出的结果看到, 输出顺序和声明顺序一致
- val map1 = Map("Alice" -> 19, "Tom" -> 20, "Jack" -> 21)
- println(map1)
- }
- }
10.20.2 方式 2 - 构造可变映射
- // 方式 2 - 构造可变映射
- //1. 从输出的结果看到, 可变的 map 输出顺序和声明顺序不一致
- val map2 = mutable.Map("Alice" -> 19, "Tom" -> 20, "Jack" -> 21)
- println(map2)
10.20.3 方式 3 - 创建空的映射
- val map3 = new scala.collection.mutable.HashMap[String, Int]
- println(map3)
10.20.4 方式 4 - 对偶元组
- 说明
即创建包含键值对的二元组, 和第一种方式等价, 只是形式上不同而已
对偶元组就是只含有两个数据的元组
- 案例演示
- // 方式 4 - 对偶元组
- val map4 = mutable.Map(("Alice" , 19), ("Tom" , 20), ("Jack" , 21))
- println("map4=" + map4)
10.21 映射 Map - 取值
10.21.1 方式 1 - 使用 map(key)
- val value1 = map2("Alice")
- println(value1)
- 说明
1) 如果 key 存在, 则返回对应的值
2) 如果 key 不存在, 则抛出异常[java.util.NoSuchElementException]
3) 在 Java 中, 如果 key 不存在则返回 null
4) 案例演示
- // 方式 1 - 使用 map(key)
- println(map4("Alice")) // 19
- // 抛出异常(java.util.NoSuchElementException: key not found:)
- //println(map4("Alice~"))
10.21.2 方式 2 - 使用 contains 方法检查是否存在 key
- // 返回 Boolean
- // 1. 如果 key 存在, 则返回 true
- // 2. 如果 key 不存在, 则返回 false
- map4.contains("T")
- 说明
使用 contains 先判断再取值, 可以防止异常, 并加入相应的处理逻辑
- 案例演示
- // 方式 2 - 使用 contains 方法检查是否存在 key
- if (map4.contains("Alice")) {
- println("key 存在, 值 =" + map4("Alice"))
- } else {
- println("key 不存在:)")
- }
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
- 案例演示
- // 方式 3 - 使用 map.get(key).get 取值
- //1. 如果 key 存在 map.get(key) 就会返回 Some(值) , 然后 Some(值).get 就可以取出
- //2. 如果 key 不存在 map.get(key) 就会返回 None
- println(map4.get("Alice").get)
- //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) 案例演示
- // 方式 4 - 使用 map4.getOrElse()取值
- 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 的元素
- 案例演示
- val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
- map5("Alice") = 20 // 更新
- println("map5=" + map5)
- 小结
1) map 是可变的, 才能修改, 否则报错
2) 如果 key 存在: 则修改对应的值, key 不存在, 等价于添加一个 key-value
10.22.2 添加 map 元素
- 方式 1 - 增加单个元素
- val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
- map5 += ("史瑞克" -> 27) // 增加
- println("map5=" + map5)
- 方式 2 - 增加多个元素
- val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
- map5 += ("史瑞克" -> 27, "灭霸" -> 100)
- println("map5=" + map5)
- 说明: 当增加一个 key-value, 如果 key 存在就是更新, 如果不存在就是添加
10.22.3 删除 map 元素
- 案例演示
- val map5 = mutable.Map( ("Alice", 19), ("Tom", "20"), ("Jack", 23) )
- map5 += ("史瑞克" -> 27, "灭霸" -> 100)
- map5 -= ("Alice","Tom","Ja")
- println("map5=" + map5)
- 说明
1) "Alice","Tom" 就是要删除的 key, 可以写多个
2) 如果 key 存在, 就删除, 如果 key 不存在, 也不会报错
10.23 映射 Map - 对 map 遍历
对 map 的元素 (元组 Tuple2 对象) 进行遍历的方式很多, 具体如下:
- import scala.collection.mutable
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- val map1 = mutable.Map( ("A", 1), ("B", 2), ("C", 3) )
- for ((k, v) <- map1) println(k + "is mapped to" + v)
- for (v <- map1.keys) println(v)
- for (v <- map1.values) println(v)
- for (v <- map1) println(v)
- }
- }
- 说明
1) 每遍历一次, 返回的元素是 Tuple2
2) 取出的时候, 可以按照元组的方式来取
- 案例演示
- import scala.collection.mutable
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- //map 的遍历
- val map6 = mutable.Map(("A", 1), ("B", 2), ("C", 3))
- println("----(k, v) <- map6--------")
- for ((k, v) <- map6) println(k + "is mapped to" + v)
- println("----v <- map6.keys--------")
- for (v <- map6.keys) println(v)
- println("----v <- map6.values--------")
- for (v <- map6.values) println(v)
- // 这样取出方式 v 类型是 Tuple2
- println("----v <- map6--------")
- for (v <- map6) println(v + "key =" + v._1 + "val=" + v._2)
- }
- }
10.24 集 Set - 基本介绍
集是不重复元素的结合, 集不保留顺序, 默认是以哈希集实现
10.24.1 Java 中 Set 的回顾
Java 中, HashSet 是实现 Set<E > 接口的一个实体类, 数据是以哈希表的形式存放的, 里面不能包含重复数据. Set 接口是一种不包含重复元素的 collection,HashSet 中的数据也是没有顺序的
10.24.2 案例演示
- import java.util.HashSet;
- public class JavaHashSet {
- public static void main(String[] args) {
- //java 中的 Set 的元素 没有顺序, 不能重复
- HashSet hs = new HashSet<String>();
- hs.add("Jack");
- hs.add("Tom");
- hs.add("Alice");
- hs.add("史瑞克");
- System.out.println(hs);
- }
- }
默认情况下, Scala 使用的是不可变集合, 如果想要使用可变集合, 需要引用 scala.collection.mutable.Set 包
10.25 集 Set - 创建
- import scala.collection.mutable
- object boke_demo01 {
- def main(args: Array[String]): Unit = {
- val set = Set(1, 2, 3) // 不可变
- println(set)
- val set2 = mutable.Set(1, 2, "hello") // 可以变
- println("set2" + set2)
- }
- }
10.26 集 Set - 可变集合的元素添加和删除
10.26.1 可变集合的元素添加
- mutableSet.add(4) // 方式 1
- mutableSet += 6 // 方式 2
- mutableSet.+=(5) // 方式 3
- 说明: 如果添加的对象已经存在, 则不会重复添加, 也不会报错
10.26.2 可变集合的元素删除
- val set3 = mutable.Set(1,2,3,"abc")
- set3 -= 2 // 操作符形式
- set3.remove("abc") // 方法的形式, scala 的 Set 可以直接删除值
- println(set3)
- // 说明: 如果删除的对象不存在, 则不生效, 也不会报错
10.26.3 Set 集合的遍历操作
- val set4 = mutable.Set(1, 2, 3, "abc")
- for (x <- set4) {
- println(x)
- }
10.27 集 Set - 更多操作
10. Scala 数据结构(上)- 集合操作
来源: http://www.bubuko.com/infodetail-3053101.html