第五章 映射、选项以及元组
1- 构造映射
在Scala中, 构造映射(Map) 是一种常见的操作, 用于创建和初始化键值对集合;
通过构造映射, 可以将键与值关联起来, 实现快速的查找访问;
种类
在Scala中, 构造映射的种类主要包括 不可变映射 (Immutable Map) 和 可变映射(Mutable Map) ;
不可变映射 (Immutable Map)
: 不可变映射在创建后不可更改, 可以通过Map
对象的apply
方法或直接Map
来创建 ;
// 创建不可变映射
val immutableMap = Map("name" -> "John", "age" -> "22")
println(immutableMap) // 输出: Map(name -> John, age -> 22)
可变映射(Mutable Map)
: 可变映射允许在创建后添加, 更新或删除键值对, 需要导入mutable.Map
;
import scala.collection.mutable.Map
// 创建可变映射
val mutableMap = Map("name" -> "John", "age" -> "22")
mutableMap("name") = "John Doe"
println(mutableMap) // 输出: Map(age -> 22, name -> John Doe)
mutableMap += ("id" -> "1001")
println(mutableMap) // 输出: Map(age -> 22, name -> John Doe, id -> 1001)
空映射
: 可以创建空的映射, 不可变映射和可变映射均支持 ;
// 创建空映射
val emptyImmutableMap = Map[String, String]()
val emptyMutableMap = Map.empty[String, String]
默认映射(Default Map)
: 可以使用withDefaultValue
方法为映射设置默认值 ;
// 创建默认映射
val defaultMap = Map("a" -> 1, "b" -> 2).withDefaultValue(0)
val value = defaultMap("c")
println(value) // 输出: 0 (如果键"c"不存在, 默认值为0)
获取映射的值
在Scala中, 可以使用通过键来获取映射 (Map) 中的值;
使用apply方法
: 可以通过在映射名称后加括号并传入键来获取对应的值 ;
val map = Map("name" -> "John", "age" -> "22")
val name = map.get("name")
println(name) // 输出: Some(John)
使用getOrElse方法
: 可以使用 getOrElse 方法获取键对应的值, 如果键不存在, 则返回默认值.
val map = Map("a" -> 1, "b" -> 22)
val valueC = map.getOrElse("c", 0)
println(valueC) // 输出: 0
使用get方法
: get方法返回一个 Option 类型的值, 可以通过模式匹配或 getOrElse 方法处理存在和不存在的情况 ;
val map = Map("a" -> 1, "b" -> 22)
val valueD = map.get("d") // 返回 Option[Int]类型的值
valueD match {
case Some(value) => println(s"值为: $value")
case None => println("键不存在") // 输出: 键不存在
}
更新映射中的值
在Scala中更新映射 (Map) 中的值有多种方法, 如下方法:
使用+操作符
: 可以使用 + 操作符来添加新的键值对或更新现有键的值;
val map = Map("a" -> 1, "b" -> 2)
val map1 = map + ("a" -> 10)
println(map1) // 输出: Map(a -> 10, b -> 2)
使用updated方法
: 可以使用updated方法来更新映射中的键值对, 返回一个新的映射;
val map = Map("a" -> 1, "b" -> 2)
val map2 = map.updated("b", 20)
println(map2) // 输出: Map(a -> 10, b -> 20)
使用+=操作符
: 对应可变映射, 可以使用 += 操作符来添加新的键值对或更新现有键的值;
import scala.collection.mutable.Map
val mutableMap = Map("a" -> 10, "b" -> 20)
mutableMap("a") = 100
mutableMap("b") += 200
mutableMap("c") = 30
println(mutableMap) // Map(b -> 220, a -> 100, c -> 30)
使用update方法
: 对于可变映射, 可以直接使用update方法更新键的值 ;
import scala.collection.mutable.Map
val mutableMap = Map("a" -> 10, "b" -> 20)
mutableMap.update("a", 100)
println(mutableMap) // 输出: Map(b -> 20, a -> 100)
迭代映射
- 使用
foreach方法
迭代映射中的键值对:
val map = Map(1 -> "one", 2 -> "two", 3 -> "three")
map.foreach { case (k, v) => println(s"Key: $k -> Value: $v")
}
/*
Key: 1 -> Value: one
Key: 2 -> Value: two
Key: 3 -> Value: three
*/
- 使用
for循环
迭代映射中的键值对:
val map = Map(1 -> "one", 2 -> "two", 3 -> "three")
for ((k, v) <- map) {
println(s"key: $k, value: $v")
}
/*
Key: 1 -> Value: one
Key: 2 -> Value: two
Key: 3 -> Value: three
*/
访问键或值
- 访问键值对的值:
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
val valueA = map("a")
println(valueA) // 输出: 1
- 查找值对应的键:
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)
val keyForValue = map.find{ case (k, v) => v == 2}.map(_._1)
println(keyForValue) // Some(b)
反转映射
可以通过调用 map.map(_.swap)
来反转映射中的键值对, 将原来的键变为值, 值变为键 ;
val map = Map(1 -> "one", 2 -> "two", 3 -> "three")
// 反正映射
val reversedMap = map.map(_.swap)
println(reversedMap) // 输出: Map(one -> 1, two -> 2, three -> 3)
已排序映射
使用 TreeMap
来创建一个已排序的映射, 它会根据键的自然顺序进行排序;
import scala.collection.immutable.TreeMap
val sortedMap = TreeMap(2 -> "two", 1 -> "one", 3 -> "three")
println(sortedMap) // 输出: Map(1 -> one, 2 -> two, 3 -> three)
2- 选项
在Scala中, 选项 (Option) 是一种用于处理可能不存在的情况的数据类型;
选项可以有两种状态: Some
表示存在值, None
表示不存在值;
-
创建选项
: 使用Some
和None
来创建选项:-
创建包含值的选项:
// 创建包含值的选项 val someOption: Option[Int] = Some(10)
-
创建空选项:
// 创建空选项 val noneOption: Option[Int] = None
-
-
访问选项中的值
: 使用模式匹配或getOrElse
方法来访问选项中的值;-
使用模式匹配
val option : Option[Int] = Some(10) option match { case Some(v) => println(s"值为: $v") // 输出: 值为: 10 case None => println("值为空") }
-
使用
getOrElse
方法// 使用 `getOrElse` 方法来获取值,如果值为空则返回默认值 `0` val value = option.getOrElse(0) // 输出: 10
-
-
选项的常见操作
map
: 对选项中的值进行映射操作flatMap
: 对选项中的值进行映射操作, 并返回新的选项filter
: 根据条件过滤选项中的值foreach
: 对选项中的值执行副作用操作
-
使用选项的好处
- 避免空指针异常: 通过使用选项, 可以更安全地除了可能为空的值
- 明确表达可能不存在值的情况: 选择可以清晰地表示某个值可能不存在的情况
3- 元组
在Scala中, 元组(Tuple) 是一种可以容纳固定数量元素的不可变数据结构;
元组可以包含不同类型的元素, 并且原则的长度是固定的;
-
创建元组
: 可以使用圆括号来创建元组, 元组的元素行1 开始索引;-
创建包含两个元素的元组:
val tuple1 = (1, "hello") println(tuple1) // 输出: (1,hello)
-
创建包含三个元素的元组:
val tuple2 = (1, "hello", 3.14) println(tuple2) // 输出: (1,hello,3.14)
-
-
访问元组中的元素
: 可以使用.
和元素的索引来访问元素中的元素;-
访问元组中的第一个元素:
val tuple2 = (1, "hello", 3.14) val firstElement = tuple2._1 println(firstElement) // 输出: 1
-
访问元组中的第二个元素:
val tuple2 = (1, "hello", 3.14) val secondElement = tuple2._2 println(secondElement) // 输出: hello
-
通过模式匹配访问元素
val tuple2 = (1, "hello", 3.14) val (x, y, z) = tuple2 println(s"x : $x, y : $y, z : $z") // 输出: x : 1, y : hello, z : 3.14
-
-
元组的特点
:- 不可变性: 元组是不可变的, 一旦创建就无法修改元素中的元素;
- 可以包含不同类型的元素: 元组可以包含不同类型的元素, 例如整数、字符串、布尔值等;
- 固定长度: 元组的长度是固定的, 无法动态添加或删除元素;
-
使用元组的场景
:- 返回多个值: 当函数需要返回多个值时, 可以使用元组来方便地返回多个值;
- 临时存储数据: 在临时存储一组相关数据时, 元组是一个方便的选择;
-
元组的操作
:-
swap
方法: 交换元组中的元素顺序, 仅限于两个元素的顺序交换, 不包含是哪个或更多元素的元组;val tuple1 = (1, "hello") val swappedTuple = tuple1.swap println(swappedTuple) // 输出: (hello,1)
-
productIterator
方法: 返回一个迭代器, 用于遍历元组中的所有元素;val tuple2 = (1, "hello", 3.14) tuple2.productIterator.foreach { element => println(s"Element: $element") } /* Element: 1 Element: hello Element: 3.14 */
-
productArity
方法: 返回元组中元素的数量;val tuple3 = (1, "Hello", 2, "World") val tupleLenght = tuple3.productArity println("tupleLenght: " + tupleLenght) // 输出: tupleLenght: 4
-
转换元组为字符串
:toStrign
方法将元组转换为字符串表示形式;val tuple3 = (1, "Hello", 2, "World") val tupleString = tuple3.toString() println(tupleString) // 输出: (1,Hello,2,World)
-
4- 常用集合操作
映射(Map)
: 对集合中的每一个元素应用一个函数, 返回一个新的集合:
val numbers = List(1, 2, 3, 4, 5)
val squaredNumbers = numbers.map(x => x * x)
println(squaredNumbers) // 输出: List(1, 4, 9, 16, 25)
过滤(Filter)
: 根据条件过滤集合中的元素, 只保留满足条件的元素
val numbers = List(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter(x => x % 2 == 0)
println(evenNumbers) // 输出: List(2, 4)
转换(Transform)
: 将集合中的元素转换为另外一种形式:
val numbers = List(1, 2, 3, 4, 5)
val decimalNumbers = numbers.map(x => x.toDouble / 2)
println(decimalNumbers) // 输出: List(0.5, 1.0, 1.5, 2.0, 2.5)
折叠(Fold)
: 将集合中的元素进行累计操作, 返回一个最终结果:
val numbers = List(1, 2, 3, 4, 5)
val sum = numbers.foldLeft(0)((acc, x) => acc + x)
println(sum) // 输出: 15
扁平化(Flatten)
: 将嵌套的集合结构展开为单层集合:
val nestedList = List(List(1, 2), List(3, 4), List(5, 6))
val flattenedList = nestedList.flatten
println(flattenedList) // 输出: List(1, 2, 3, 4, 5, 6)
zip
: 将两个集合的对应元素组合成元组:
val list1 = List(1, 2, 3)
val list2 = List('a', 'b', 'c')
val zippedList = list1.zip(list2)
println(zippedList) // 输出: List((1,a), (2,b), (3,c))
partition
: 根据条件将集合分成两部分:
val list = List(1, 2, 3, 4, 5, 6)
val (even, odd) = list.partition(_ % 2 == 0)
println(s"even: $even,odd: $odd") // 输出: even: List(2, 4, 6), odd: List(1, 3, 5)
find
: 查找集合中满足条件的第一个元素:
val list4 = List(1, 2, 3, 4, 5)
val found1 = list4.find(_ % 2 == 1)
println(found1) // 输出: Some(1)
val found2 = list4.find(_ % 2 == 0)
println(found2) // 输出: Some(2)
val found3 = list4.find(_ > 3)
println(found3) // 输出: Some(4)
drop
: 丢弃集合中的前n个元素:
val list5 = List(1, 2, 3, 4, 5)
val droppedList = list5.drop(2)
println(droppedList) // 输出: List(3, 4, 5)
dropWhile
: 丢弃集合中满足条件的元素, 直到遇到第一个不满足条件的元素:
val list6 = List(1, 2, 3, 4, 5)
val droppedWhileList = list6.dropWhile(_ < 3)
println(droppedWhileList) // 输出: List(3, 4, 5)
val droppedWhileList2 = list6.dropWhile(_ % 2 == 1)
println(droppedWhileList2) // 输出: List(2, 3, 4, 5)
flatMap
: 对集合中的每个元素应用一个函数, 并将结果扁平化为单个集合:
val list7 = List(1, 2, 3, 4)
val flatMapList = list7.flatMap(x => List(x, x * 2))
println(flatMapList) // 输出: List(1, 2, 2, 4, 3, 6, 4, 8)