Scala学习笔记6--容器

本文详细探讨了Scala中的可变与不可变容器,重点讲解了Set、Map和List的操作,包括创建、过滤、添加、合并等。强调了不可变容器在线程安全和程序正确性方面的优势,并提供了示例代码展示如何在实践中使用这些容器。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

可变容器与不可变容器

Scala虽然也提供了可变的(mutable)容器,但它更倾向于使用不变的(immutable)版本。不变容器不仅线程安全,而且没有副作用,有助于提升程序的正确性。在两个可供选择的包,只要在两个包选择一个即可:scala.collection.mutable或scala.collection.im-mutable。默认情况下,我们用的是不可变Set和Map

Set

  • 创建容器
val feeds1 = Set("blog.toolshed.com", "pragdave.pragprog.com",  "pragmactic-osxer.blogspot.com", "vita-contemplativa.blogspot.com")
val feeds2 = Set("blog.toolshed.com", "martinfowler.com/bliki")
  • filter 过滤
val blogSpotFeeds = feeds1 filter ( _ contains "blogspot" )
  • +=() 添加
feeds1 += 'www.baidu.com'
  • ++() 合并
val mergedFeeds = feeds1 ++ feeds2
  • size 元素个数
println("# of merged feeds: " + mergedFeeds.size)
  • **() 交集
val commonFeeds = feeds1 ** feeds2
  • map 处理每个元素,并返回结果集
val urls = feeds1 map ( "http://" + _ )
  • foreach 迭代处理每个元素
feeds1 foreach { 
    feed => println(" Refreshing " + feed ) 
}
  • toArray 复制到数组
println("One url: " + urls.toArray(0))
  • mkString 合并成字符串
println(feeds.mkString(','))

Map

  • 创建容器
val feeds = Map("Andy Hunt" -> "blog.toolshed.com",
    "Dave Thomas" -> "pragdave.pragprog.com",  
    "Dan Steinberg" -> "dimsumthinking.com/blog")
  • filterKeys() 按键过滤
val filterNameStartWithD = feeds filterKeys( _ startsWith "D" )
  • filter() 按键和值过滤
val filterNameStartWithDAndBlogInFeed = feeds filter { element =>  
    val (key, value) = element  
    (key startsWith "D") && (value contains "blog") 
}
  • get() 取值
println("Get Andy's Feed: " + feeds.get("Andy Hunt"))

get()的返回类型是Option[T],结果可能是Some[T]或是None,其中T是Map里值的类型。

  • apply() 取值
try {  
    println("Get Andy's Feed Using apply(): " + feeds("Andy Hunt"))  
    print("Get Bill's Feed: ")  println(feeds("Bill Who"))} 
    catch {
      case ex : java.util.NoSuchElementException => println("Not found") 
}

,apply()方法返回的不是Option[T],而是值。不同于get(),如果给定的键值没有对应的值,就会抛出异常。所以,请确保代码放到了一个try-catch块里

  • update 显式调用(添加元素)
val newFeeds1 = feeds.update("author", "blog")

若使用不变容器,update()并不会影响原来的Map。相反,它会返回一个新的Map,包含了新增的元素。

  • update 隐式调用
valnewFeed = feeds("author") = "blog" //等价于下式
valnewFeed = feeds.update("author", "blog")

如果对赋值左边的类或实例使用括号,Scala会自动调用update()方法。所以,X() = b等价于X.update(b)。如果update()的参数多于一个,可以将除了最后一个参数之外的所有参数放到括号里。所以,X(a) = b等价于X.update(a, b)。

  • 可变Map
val mutableFeeds = scala.collection.mutable.Map("author" -> "bill")
mutableFeeds("title")= "learning java"

List

和Set和Map不同,List只有不变实现。

  • 创建LIst
val feeds = List("blog.toolshed.com", "pragdave.pragprog.com",  "dimsumthinking.com/blog")
  • 访问List
println("First feed: " + feeds.head)
println("Second feed: " + feeds(1))
  • ::() 添加元素(头部)
val prefixedList = "forums.pragprog.com/forums/87" :: feeds
  • :::() 连接List
val feedsWithForums =  feeds ::: List("forums.pragprog.com/forums/87", "forums.pragprog.    com/forums/55")
  • filter 过滤
println("Feeds with blog: " + feeds.filter( _ contains "blog" ).  mkString(", "))
  • foreall 判断所有元素是否满足条件
feeds.forall( _ contains "com" ))
  • exists 判断是否存在元素满足条件
feeds.exists( _ contains "dave" ))
  • map 处理每个元素,并返回结果集
println("Feed url lengths: " + feeds.map( _.length ).mkString(", "))
  • foldLeft
val total = feeds.foldLeft(0) { (total, feed) => total + feed.length }

foldLeft()方法会从List的最左端开始为List的每个元素调用给定的函数值。函数值的第一个参数是上一次函数值执行的结果,第二个参数是List的元素。foldRight()做相同的事,不过是从右边开始。

  • foldLeft的另一种调用/:
val total2 = (0 /: feeds) { (total, feed) => total + feed.length }

foldRight的另一种调用:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值