scala映射和元组浅谈及代码示例分享

scala映射和元组浅谈及代码示例分享

      映射是键/值的对偶集合。Scala有一个通用的叫法–元组–n个对象的聚集,这些对象并不一定是相同类型的。对偶不过是一个n=2的元组。元组在那种需要将两个或更多值聚集在一起的场合特别有用。

一、构造映射:

a.不可变映射:

//两种方式都可以
val scores = Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8)
val scores = Map(("Alice",10), ("Bob", 3),("Cindy",8))

b.可变映射:

val scores = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8)

c.可变空映射:

val scores = scala.collection.mutable.Map[String,Int]()

      映射是一种将键映射到值的函数。只不过两者的区别在于,通常函数用于计算值,而映射仅用于查询值。

二、获取映射中的值:

      在scala中,函数和映射之间的相似性尤为明显,因为你将使用()表示法来查询某个键对应的值。

  val scores = Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8)
  val bobsScore = scores("Bob")

      如果映射中不包含请求中使用的键则会抛出空指针异常。想要检查映射中是否有某个指定的键可以使用contains方法:

val scores = Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8)
// 写法1
val bobsScore = if (scores.contains("Bob")) scores("Bob") else "not matches..."
// 写法2
val bobsScore = scores.getOrElse("Bob","not matches...")

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

val scores = Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8)
val zel = scores.get("Bob") //返回Some(3)
val zel = scores.get("zelda") // 返回None,因为不存在zelda这个键
三、更新映射中的值:

      在可变映射中,可以更新某个映射的值,或添加一个新的映射关系,做法是在=的左边使用()。

val scores = scala.collection.mutable.Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8, "Lee" -> null)
scores("Lee") = 9
scores("Ann") = 8
// 输出为 HashMap(Ann -> 8, Bob -> 3, Cindy -> 8, Lee -> 9, Alice -> 10)

      也可以使用+=来添加其他或修改映射关系,或使用-=来删除已有的键。

scores += ("Alice" -> 12,"Tony" -> 15) //修改Alice分数为12,添加Tony分数为15
scores -= ("Alice") //删除Alice的映射关系

      虽然不能更新不可变映射,但是可以获取一个包含修改的新映射:

val scores = Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8, "Lee" -> null)
val scores1 = scores + ("Alice" -> 12,"Tony" -> 15)
// 输出为HashMap(Bob -> 3, Tony -> 15, Alice -> 12, Lee -> null, Cindy -> 8)

      或者在创建时直接创建var变量:

var scores = Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8, "Lee" -> null)
scores += ("Alice" -> 12,"Tony" -> 15)
// 输出为HashMap(Bob -> 3, Tony -> 15, Alice -> 12, Lee -> null, Cindy -> 8)
四、迭代映射:

      下面是一个简单的迭代映射的例子:

for((k,v) <- 映射) 处理 k 和 v

      在这个例子中,使用了for循环中的模式匹配。这样一来,不需要冗杂的方法调用,就可以得到每一个对偶的键和值。
      如果出于某些原因,只需要访问键或值,则可以使用keySet和values方法。values方法返回一个Iterable,这个iterable可以在for循环中使用。

var scores = Map("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8, "Lee" -> null)
scores += ("Alice" -> 12,"Tony" -> 15)
println(scores.keySet)
//输出为Set(Bob, Tony, Alice, Lee, Cindy)
println(scores.values)
//输出为Iterable(3, 15, 12, null, 8)

      此外要执行映射反转时还可使用以下语句:

val result1 =for ((k,v)<- scores) yield (v,k)
五、已排序映射:

      映射有两种常见的实现策略:哈希表和平衡树。哈希表使用键的哈希码来划定位置,因此遍历会以一种不可预期的顺序交出元素。默认情况下,Scala给你的是基于哈希表的映射,因为它比较高效。如果需要按照顺序依次访问映射中的键,可以使用SortedMap。

val scores = scala.collection.mutable.SortedMap("Alice" -> 10, "Bob" -> 3,"Cindy" -> 8, "Lee" -> null)
scores += ("Alice" -> 12,"Tony" -> 15)
println(scores)
//输出为TreeMap(Alice -> 12, Bob -> 3, Cindy -> 8, Lee -> null, Tony -> 15),可以看到是按顺序输出的,按插入顺序输出则可以使用,LinkedHashMap
六、与Java的互操作:

      如果通过Java方法调用得到了一个Java映射,你可能想要把它转换为一个Scala映射,以便使用更加便捷的Scala映射API。这对于需要操作Scala并未提供的可变树形映射的情况很有用。
      只需要引入如下语句:

import scala.collection.JavaConverters.mapAsScalaMap

      然后通过指定的Scala映射类型来触发转换:

val scores:scala.collection.mutable.Map[String,Int]= new java.util.TreeMap[String,Int]

      此外,你还可以得到从java.util.Properties到Map[String,String]的转换:

import scala.collection.JavaConversions.propertiesAsScalaMap
val props : scala.collection.Map[String,String] = System.getProperties()

      相反,要把Scala映射传递给预期Java映射的方法,提供相反的隐式转换即可。

import scala.collection.JavaConversions.mapAsJavaMap
import java.awt.font.TextAttribute //引入下面的映射会用到的键
val attrs = Map(FAMILY->"Serif",SIZE->12) //Scala映射
val font = new java.awt.Font(attrs) //该方法预期产生一个Java映射
七、元组:

      映射是键值对偶的集合。对偶是元组最简单的形态–元组是不同类型的值的聚集。
      元组的值是通过将单个的值包含在圆括号中构建的。例如:

val a = (1, 3.14, "Fred")

      可以使用方法_1、_2、_3访问元组的组元。

val second = a._2

      和数组或字符串中的位置不同,元组的各组元是从1开始的,而不是从0开始的。
      通常使用模式匹配来获取元组的组成部件,例如:

val (first,second,third) = a // first为1,second为3.14,third为"Fred"

      如果并不是所有部件都需要,可以在不需要的部件位置上使用_:

val (first,second,_) = a

      元组可以用于函数需要返回不止一个值的情况。例如,StringOps的partition方法返回的是一对字符串,分别包含了满足某个条件和不满足某个条件的字符:

"New York".partition(_.isUpper) //返回("Ny","ew ork")
八、拉链操作:

      使用元组的原因之一是把多个值绑在一起,以便它们能够被一起处理,这通常可以使用zip方法来完成。

  val symbols = Array("<","-",">")
  val counts = Array(2,10,2)
  val pairs = symbols.zip(counts)
  for((s,n) <- pairs) print(s * n) 
  // 输出为<<---------->>,即2个<、10个-、2个>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值