前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Play For Scala 开发指南 - 第3章 常用类介绍

Play For Scala 开发指南 - 第3章 常用类介绍

作者头像
joymufeng
发布2018-05-17 15:57:03
8110
发布2018-05-17 15:57:03
举报
3.1 String

在Scala中,String更加方便好用:

代码语言:javascript
复制
//原始字符串一对三引号"""括起来,可包含多行字符串,内容不需要转义
"""Welcome here.
   Type "HELP" for help!"""
   
//类型转换
"100.0".toDouble

//判断字符串相等直接用"==",而不需要使用equals方法
val s1 = new String("a")
s1 == "a" // true

//字符串去重
"aabbcc".distinct // "abc"

//取前n个字符,如果n大于字符串长度返回原字符串
"abcd".take(10) // "abcd"

//字符串排序
"bcad".sorted // "abcd"

//过滤特定字符
"bcad".filter(_ != 'a') // "bcd"

//字符串插值, 以s开头的字符串内部可以直接插入变量,方便字符串构造
val i = 100
s"i=${i}" // "i=100"

Scala中没有受检异常(checked exception),所以你没有必要声明受检异常,如果真的发生异常,则会在运行时抛出。

3.2 Option

Scala用Option类型表示一个值是否存在,用来避免Java的NullPointerException。它有两个子类:Some和None。Some类型表示值存在,None类型则表示值不存在。 常用操作:

代码语言:javascript
复制
val opt: Option[String] = Some("hello")
//判断是否为None
opt.isEmpty // false
//如果为None,则返回默认值"default",否则返回opt持有的值
opt.getOrElse("default") 
//如果为None则返回"DEFAULT",否则将字符转为大写
opt.fold("DEFAULT"){ value => value.toUpperCase } // "HELLO"
//功能同上
opt match {
  case Some(v) => v.toUpperCase
  case None => "DEFAULT"
}
3.3 List

在Scala中,List要么是Nil(空列表),要么就是由head和tail组成的递归结构。 head是首元素,tail是剩下的List。所以你可以这样构建List:

代码语言:javascript
复制
val list = 1 :: Nil // 等价于:val list = List(1)

连续的两个冒号"::"就像是胶水,将List的head和tail粘在一起。 常用操作:

代码语言:javascript
复制
val list = List(1, 3, 2)
//获取第1个元素
list.headOption.getOrElse(0) // 1
//查找
list.find(_ % 2 == 0).getOrElse(0) // 2
//过滤
list.filter(_ % 2 == 1) // List(1, 3)
//排序
list.sorted // List(1, 2, 3)
//最小值/最大值/求和
list.min // 1
list.max // 3
list.sum // 6
//转化成字符串
list.mkString(",") // "1, 3, 2"

Scala提供的List基本可以实现SQL查询的所有功能,这也是Spark为什么基于Scala开发的原因。更多功能请参考官方文档

在Scala中默认的集合类例如List,Set,Map,Tuple等都是不可变的,所以调用其修改方法会返回一个新的实例。如果要使用可变集合,请使用scala.collection.mutable包下相应的类。不可变类型在编写并发代码时很有用。

3.4 Tuple

Tuple(元组)Tuple可以容纳不同类型的元素,最简单的形态是二元组,即由两个元素构成的Tuple, 可以使用_1, _2等方法访问其元素:

代码语言:javascript
复制
val t = ("a", 1) // 等价于:val t: Tuple2[String, Int] = ("a", 1)
t._1 // "a"
t._2 // 1

也可以使用模式匹配利用Tuple同时初始化一组变量:

代码语言:javascript
复制
val t = ("a", 1)
val (v1, v2) = t
v1 // "a"
v2 // 1
3.5 Map

Map其实是二元组的集合:

代码语言:javascript
复制
val map = Map("a" -> 1, "b" -> 2)

"->"其实是String类型上的方法,返回一个二元组:

代码语言:javascript
复制
"a" -> 1 //等价于: ("a", 1)

所以你也可以这样构建Map:

代码语言:javascript
复制
val map = Map(("a", 1), ("b", 2))

常用操作:

代码语言:javascript
复制
val map = Map("a" -> 1, "b" -> 2)
//读取
map("a") // 1
//写入或添加键值
map("a") = 0
//删除键值
map - "a" // Map(b -> 2)
3.6 Future

Future和Promise是Scala提供的最吸引人的特性之一,借助Future和Promise你可以轻松地编写完全异步非阻塞的代码,这在多处理器时代显得格外重要。

Future用于获取异步任务的返回结果。Future有两种状态:完成(completed)和未完成(not completed)。处于完成状态的Future可能包含两种情况的信息,一种是异步任务执行成功了,Future中包含异步任务执行成功的返回结果;另一种是异步任务执行失败了,Future中包含了相应的Exception信息。Future的独特之处在于它的值只能被写入一次,之后就会变为一个不可变值,其中包含成功或失败信息。你可以在Future上注册一个回调函数,以便在任务执行完成后得到通知:

代码语言:javascript
复制
import scala.concurrent.ExecutionContext.Implicits.global
val f = Future{ 1 + 2 }
f.onComplete{ t =>
  t match{
    case Success(v) => println("success: " + v)
    case Failure(t) => println("failed: " + t.getMessage)
  }
}
//等待任务结束
Await.ready(f, 10 seconds)

onComplete方法接受一个一元函数,类型为:Try[T] => U。Try类型和Option类型很像,也有两个子类SuccessFailure,前者表示任务执行成功,后者表示任务执行失败。

第1行import语句导入了一个隐式的ExecutionContext,你可以把它理解成是一个线程池,Future类在需要时会自动使用其上的线程。在Scala中你不需要直接和线程打交道。

由于Future也是一个容器类,所以可以使用for语句取回它的值:

代码语言:javascript
复制
val f = Future{ 1 + 2 }
for(v <- f) {
    println(v) // 3
}

也可以使用map方法对任务结果进行转换:

代码语言:javascript
复制
val f1 = Future{ 1 + 2 }
val f2 = f1.map(v => v % 2)
for(v <- f2) {
    println(v) // 1
}

利用for语句可以等待多个Future的返回结果:

代码语言:javascript
复制
val f1 = Future{ 1 + 2 }
val f2 = Future{ 3 + 4 }
for{
    v1 <- f1
    v2 <- f2
} {
    println(v1 + v2) // 10
}

结合yield可以返回一个新的Future:

代码语言:javascript
复制
val f1 = Future{ 1 + 2 }
val f2 = Future{ 3 + 4 }
val f3 =  
    for {
        v1 <- f1
        v2 <- f2
    } yield {
        v1 + v2
    }
3.7 Promise

有时我们需要精细地控制Future的完成时机和返回结果,也就是说我们需要一个控制Future的开关,没错,这个开关就是Promise。每个Promise实例都会有一个唯一的Future与之相关联:

代码语言:javascript
复制
val p = Promise[Int]()
val f = p.future
for (v <- f) { println(v) }

//3秒钟之后返回3
Thread.sleep(3000)
p.success(3)

//等待任务结束
Await.ready(f, 10 seconds)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.1 String
  • 3.2 Option
  • 3.3 List
  • 3.4 Tuple
  • 3.5 Map
  • 3.6 Future
  • 3.7 Promise
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档