【Scala】Scala之String
⼀、前⾔
⼤数据领域的Spark、Kafka、Summingbird等都是由Scala语⾔编写⽽成,相⽐Java⽽⾔,Scala更精炼。由于笔者从事⼤数据相关的⼯作,所以有必要好好学习Scala语⾔,之前也学习过,但是没有记录,所以就会忘记,感觉Scala确实⽐Java⽅便精炼很多,下⾯以Scala Cookbook英⽂版作为参考资料,从头到尾梳理Scala相关知识点,也加深印象。PS:这是在研究Zookeeper源码的间隙中交叉学习,不⾄于总是看源码太枯燥。
⼆、String
在Scala的REPL环境中测试String的类型,可以发现其就是Java中的String。
所以可以使⽤Java中String的所有⽅法,如获取字符串的长度、连接多个字符串。在Scala中,由于String可以被隐式转化成StringOps类型,可将字符串看成⼀个字符序列,并且可以使⽤foreach⽅法遍历字符串的每个字符。
也可将字符串当成字符序列,使⽤for循环遍历每个字符
同理,也可将字符串当前字节序列,使⽤for循环遍历
由于字符串可以当成字符顺序集合(字符序列),⽽在集合上可进⾏多种操作,如filter
可以看到对字符串进⾏了过滤,去掉了l字符。filter⽅法是StringOps的⽅法,由于String会被隐式的转化为StringOps,因此可以调⽤此⽅法。
对于该隐式转化,是在Perdef对象中定义。
@inline implicit def augmentString(x: String): StringOps = new StringOps(x)
向封闭类中添加⽅法
在Java中,String被定义成final的,即⽆法继承String类或者添加任何⽅法,但在Scala中,我们可以通过隐式转化添加⽅法,下⾯例⼦展⽰了Scala的String拥有String的特性和集合的特性。
其中,drop⽅法和take⽅法都是Scala的序列(集合)的⽅法,⽽capitalize⽅法则是StringOps的⽅法,这种调⽤都是通过隐式转化完成的。
2.1 测试String的相等性
1. 问题描述
你需要⽐较两个字符串以判断它们是否相等,或者它们包含相同的字符序列。
2. 解决⽅案
定义了如下字符串s1、s2、s3
使⽤"=="进⾏相等性判断
可以看到s1、s2、s3均相等,⽽对于⼀个好的"=="⽅法⽽⾔,即便是有参数为空,也不会抛出异常。
若在⽐较过程中不区分⼤⼩写,则可将字符串转化成⼤写或⼩写进⾏⽐较。
然⽽,在对空字符串调⽤toUpperCase⽅法会抛出异常。
在Java中,想要⽐较不区分⼤⼩写⽐较两个字符串是否相等,则使⽤equalsIgnoreCase⽅法
3. 讨论
在Scala中,我们使⽤==⽅法来判定对象的相等性,这与Java不同,Java使⽤equals⽅法判定两个对象的相等性,== 是⽐较两个对象是否是同⼀个对象(内存地址相同)。在Scala中,== ⽅法在AnyRef(所有引⽤类型的⽗类)中定义,其⾸先会检查空值,然后再调⽤第⼀个对象的equals⽅法进⾏⽐较,因此,当⽐较两个字符串是否相等时,我们不需要检查空值。
2.2 创建多⾏字符串
1. 问题描述
在Scala源码中想要创建多⾏字符串。
2. 解决⽅案
在Scala中,你可以使⽤三个双引号来创建多⾏字符串。
val s1 = """This is
a multiline
String
"""
println(s1)
3. 讨论
使⽤上述⽅法可以创建多⾏字符串,但是当打印时,其结果如下
replaceall()This is
a multiline
String
第⼆⾏和第三⾏是以空格开头,若需要使第⼆⾏、第三⾏的字符串都不以空格开头,则可进⾏如下处理。
val s1 =
"""
|This
|is a multiline
|String
""".stripMargin
println(s1)
结果如下
This
is a multiline
String
即通过|来处理,或者使⽤其他符号,如#,同时使⽤stripMargin⽅法。
val s1 = """This is
#a multiline
#String
""".stripMargin('#')
println(s1)
结果如下
This is
a multiline
String
上述例⼦中,在第⼀⾏is和第⼆⾏multiline后⾯均隐藏了\n字符进⾏换⾏,当需要将多⾏字符串合并为⼀⾏时,可以在使⽤stripMargin⽅法之后使⽤replaceAll⽅法来将所有的\n替换为" "。
另外,在三引号字符串中可以包含特殊字符,⽽并不需要转义符进⾏转义。
2.3 分割字符串
1. 问题描述
你需要使⽤分割字符来分割字符串,如从逗号分隔(CSV)或管道分隔的⽂件中获取字符串。
2. 解决⽅案
可以使⽤String的split⽅法进⾏分割
split⽅法会返回String数组。
3. 讨论
split函数的参数可以是正则表达式,所以对于CSV⽂件,你可以使⽤逗号进⾏分割字符串。
可以看到,通过","进⾏分割时,结果中还包含了⼀些空格,如" milk", " butter", " Coco Puffs",此时,需要使⽤trim函数来去掉空格。
我们也可以使⽤正则表达式来分割字符串
split⽅法是重载的,⼀部分从Java的String⽽来,⼀部分从Scala的StringLike⽽来,例如,你可以使⽤字符⽽⾮字符串作为参数来调⽤split,此时,你使⽤的是StringLike的⽅法
此时,使⽤字符和字符串作为参数两者的结果是相同的。
2.4 将变量替换成字符串
1. 问题描述
如同Perl、PHP、Ruby⼀样,你需要将变量替换成字符串。
2. 解决⽅案
为在Scala中使⽤字符串插值,字符串前⾯需要使⽤字母s,同时需要将变量包含在字符串中,⽽每个变量名前⾯是⼀个$字符。
当在字符串前⾯使⽤字母s时,表⽰正在创建⼀个已处理的字符串字⾯量,即可以在字符串中直接使⽤变量。
字符串字⾯量中使⽤表达式
除了在字符串中使⽤变量外,同样也可以在字符串中使⽤表达式,此时表达式需要放在中括号内。
也可以使⽤中括号打印对象的属性。
s是⼀个⽅法
放在字符串字⾯量前⾯的s实际上是⼀个⽅法,⽽使⽤s⽅法可以让你享受如下便利
· Scala提供了其他现成的插值函数
· 你可⾃定义字符串插值函数
f字符串插值(printf格式)
在讨论中提到,weight被打印成65,但是如果需要在weight后⾯增加多位⼩数点应该怎么做,可以使⽤f字符串插值⽅法,其可以格式化字符串中的说明符。
为使⽤f字符串插值,⾸先需要在字符串前⾯添加f,然后在变量后⾯使⽤printf格式化说明符。
粗插值
除了使⽤s和f插值⽅法外,Scala还包括了粗插值⽅法,其会保留字符串中的特殊字符。
可以看到使⽤raw修饰字符串时,其会保留字符串中的特殊字符。
下表列出了最常⽤的说明符
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论