1 Scala中映射的操作
1.1构造映射
下列代码构建了一个不可变的Map[String,Int],其值不能改变
scala> val stores = Map("Alice" -> 10,"Bob" -> 3,"Cindy" -> 8)
stores: scala.collection.immutable.Map[String,Int] = Map(Alice -> 10, Bob -> 3, Cindy -> 8)
要想构建可变的映射,我们可以使用下面这种方式。
scala> val stores = scala.collection.mutable.Map("Alice" -> 10,"Bob" -> 3,"Cindy" -> 8)
stores: scala.collection.mutable.Map[String,Int] = Map(Bob -> 3, Alice -> 10, Cindy -> 8)
在Scala程序中,映射是对偶
的集合,对偶
简单地说就是两个值构成的组,这两个值并不一定是同一类型的,比如说("Alice" -> 10)
->
操作符用来创建对偶,我们也可以使用下面这种方式来定义映射
scala> val stores = Map(("Alice",10),("Bob",3),("Cindy",8))
stores: scala.collection.immutable.Map[String,Int] = Map(Alice -> 10, Bob -> 3, Cindy -> 8)
1.2 获取映射的值
scala> stores("Bob")//类似于java中的stores.get("Bob")
res3: Int = 3
如果映射中不包含请求中使用的键,则会抛出异常
scala> stores("Bob1")
java.util.NoSuchElementException: key not found: Bob1
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.MapLike$class.apply(MapLike.scala:141)
at scala.collection.AbstractMap.apply(Map.scala:59)
... 32 elided
检查是否包含指定的键,使用contains
方法
scala> stores.contains("Bob")
res5: Boolean = true
如果映射包含键,则返回值,否则返回0
scala> stores.getOrElse("Bob",0)
res6: Int = 3
1.3 更新映射的值
在scala中可以通过在=
的左侧使用()
更新或者添加映射关系
scala> val scores = scala.collection.mutable.Map("hadoop" -> 30, "spark" -> 20, "flink" -> 30)
scores: scala.collection.mutable.Map[String,Int] = Map(spark -> 20, hadoop -> 30, flink -> 30)
//修改映射关系
scala> scores("hadoop") = 1000
scala> scores
res8: scala.collection.mutable.Map[String,Int] = Map(spark -> 20, hadoop -> 1000, flink -> 30)
//新增映射
scala> scores("storm") = 400
scala> scores
res11: scala.collection.mutable.Map[String,Int] = Map(spark -> 20, hadoop -> 1000, flink -> 30, storm -> 400)
//批量操作
scala> scores += ("spark" -> 200, "hive" -> 50)
res12: scores.type = Map(spark -> 200, hadoop -> 1000, flink -> 30, hive -> 50, storm -> 400)
//删除操作
scala> scores -= "storm"
res13: scores.type = Map(spark -> 200, hadoop -> 1000, flink -> 30, hive -> 50)
1.4 迭代映射
scala> for (key <- scores.keys) { println(key) }
spark
hadoop
flink
hive
scala> for (value <- scores.values) { println(value) }
200
1000
30
50
scala> for ((key,value) <- scores) { println(key +":"+value) }
spark:200
hadoop:1000
flink:30
hive:50
1.5 排序映射
可能你已经注意到了,在前面的例子中,映射的键是无序的(插入和遍历的顺序不一致)。如果我们想有顺序的访问所有的键,我们可以使用LinkedHashMap
scala> val scores = scala.collection.mutable.LinkedHashMap("hadoop" -> 30, "spark" -> 20, "flink" -> 30)
scores: scala.collection.mutable.LinkedHashMap[String,Int] = Map(hadoop -> 30, spark -> 20, flink -> 30)
scala> for ((key,value) <- scores) { println(key +":"+value) }
hadoop:30
spark:20
flink:30
另一个与之相对的是TreeMap
,这里的TreeMap
是immutable
包下的,保证映射按照字典顺序排序
scala> val scores01 = scala.collection.immutable.TreeMap("B" -> 20, "A" -> 10, "C" -> 30)
scores01: scala.collection.immutable.TreeMap[String,Int] = Map(A -> 10, B -> 20, C -> 30)
scala> for ((key,value) <- scores01) { println(key +":"+value) }
A:10
B:20
C:30
2. 元组(Tuple)
2.1元组的定义
元组与数组类似,但是数组中所有的元素必须是同一种类型,而元组则可以包含不同类型的元素。
//元组的定义
scala> var tuple = (1,3.14,"Fred")
tuple: (Int, Double, String) = (1,3.14,Fred)
//访问元组的元素采用._ 是基一的。
scala> val c = tuple._2
c: Double = 3.14
模式匹配
可以通过模式匹配来获取元组中的值并赋予对应的变量:
scala> val (a,b,c)=tuple
a: Int = 1
b: Float = 3.24
c: String = Fred
如果某些位置不需要赋值,则可以使用下划线代替:
scala> val (a,_,_)=tuple
a: Int = 1
2.2 zip方法
object ScalaApp extends App {
val array01 = Array("hadoop", "spark", "storm")
val array02 = Array(10, 20, 30)
// 1.zip 方法得到的是多个 tuple 组成的数组
val tuples: Array[(String, Int)] = array01.zip(array02)
// 2.也可以在 zip 后调用 toMap 方法转换为 Map
val map: Map[String, Int] = array01.zip(array02).toMap
for (elem <- tuples) { println(elem) }
for (elem <- map) {println(elem)}
}
// 输出
(hadoop,10)
(spark,20)
(storm,30)
(hadoop,10)
(spark,20)
(storm,30)