【Scala】Scala之String(二)

简介:  大数据领域的Spark、Kafka、Summingbird等都是由Scala语言编写而成,相比Java而言,Scala更精炼。由于笔者从事大数据相关的工作,所以有必要好好学习Scala语言,之前也学习过,但是没有记录,所以就会忘记,感觉Scala确实比Java方便精炼很多,下面以Scala Cookbook英文版作为参考资料,从头到尾梳理Scala相关知识点,也加深印象。PS:这是在研究Zookeeper源码的间隙中交叉学习,不至于总是看源码太枯燥。

2.5 一次处理字符串的一个字符

  1. 问题描述

  你需要遍历字符串的每个字符,并且对每个字符做相应的操作。

  2. 解决方案

  可以使用map方法、foreach方法、for循环等方法来遍历字符串。

  40.png

  或者使用下划线的方式

  41.png

  对于字符串的字符序列,你可以使用链式调用来得到想要的结果,在下面的示例中,filter方法用于原始的字符串来生成新的字符串(去掉所有的字符l),然后再调用map方法将新生成的字符串转化为大写。

  42.png

  使用for循环和yield也可以达到map方法的效果

  43.png

  map方法、for和yield方法可以将旧的集合转化为新的集合,而foreach方法则是对集合的每个元素进行操作,不会产生新的结果。

  3. 讨论

  由于Scala将字符串当成是字符序列,而Scala也是面向对象和函数编程语言,在Java中,你可以使用如下方法来遍历字符串中的每个字符 

String s = "hello"
for (int i = 0; i < s.length(); i++) {
    char c = s.charAt(i);
    System.out.println(c);    
}

 理解map方法的工作机制

  在map方法中,你可以传入一大段代码块

  50.png

  上述功能是将字符串的字符由大写变换成小写,由于是调用的String的map方法,因此每次只会处理字符串的一个字符,map会将String当成一个字符顺序集合,map方法有一个隐式循环,在此循环中,每次只会传入一个字符。除了在map方法中直接传入代码块外,也可以先定义好函数,然后再传入map,这样可以保证代码的简洁性。

  51.png

  并且也可以在for循环和yield中使用该方法

  52.png

  除了使用方法方式外,还可以使用函数方式来完成上述的操作

  53.png

  

2.6 在字符串中查找模式

  1. 问题描述

  你需要确定字符串是否包含正则表达式模式。

  2. 解决方案

  通过String的.r方法来创建一个Regex对象,之后当查找第一个匹配时,使用findFirstIn方法,而查找所有匹配时,使用findAllIn方法。

  54.png

  对于findAllIn方法而言,可以将结果转化成Array、List、Seq等

  55.png

  3. 讨论

  使用字符串的.r方法是创建Regex对象最简单的方式,另外一种方式是导入Regex类,创建一个Regex实例,之后使用实例的方法

  56.png

  处理findFirstIn返回的结果

  findFirstIn查找第一个匹配并且返回一个Option[String]

  Option/Some/None类型将会在之后的章节进行讨论,可以简单的认为Option是一个容器,它要么持有0或者一个值,对于findFirstIn,成功时会返回Some("123"),不成功时会返回None

  57.png

  返回类型为Option[String]的方法要么返回Some(String),要么返回None

  针对Option类型,想要获取其值,可以使用如下方法

    · getOrElse

    · 使用foreach

    · 使用匹配表达式 

  使用getOrElse方法,你可以尝试获取值,或者失败时定义缺省值

  58.png

  使用foreach方法如下

  59.png

  使用匹配表达式方法如下

  60.png

  

2.7 字符串的替换模式

  1. 问题描述

  你需要要在字符串中搜索正则表达式模式,并替换它们。

  2. 解决方案

  由于String是不可变的,所以你不能直接在字符串上进行查找并替换的操作,但是你可以创建包含替换内容的新字符串,可以使用replaceAll方法,要记得将结果赋值

  61.png

  也可创建一个正则表达式,然后调用replaceAllIn方法,同样要记得将结果赋值给新的字符串

  62.png

  也可以调用replaceFirstIn来替换第一个匹配值,同样要记得将结果赋值给新的字符串

  63.png

  

2.8 提取模式匹配的字符串部分

  1. 问题描述

  你需要提取字符串的一个或多个匹配正则达表达式的部分。

  2. 解决方案

  首先定义提取的正则表达式模式,然后将它们放置在括号里面形成正则表达式组

  64.png

  上述示例从指定字符串中提取了数字部分和字母部分,并且分别赋值给count和fruit。

  3. 讨论

  上述示例的语法可能有点古怪,似乎是将模式两次定义成val字段,但是这种语法很便捷并且可读性很高,可以试想你在编写一个搜索引擎,你想让人们用各种各样的短语搜索电影,你可以让他们输入任何这些短语来获得电影列表

  65.png

  你可以定义一系列的正则表达式进行匹配,例如

// match "movies 80301"
val MoviesZipRE = "movies (\\d{5})".r
// match "movies near boulder, co"
val MoviesNearCityStateRE = "movies near ([a-z]+), ([a-z]{2})".r


 之后可以根据用户的输入进行匹配,然后获取搜索结果,伪代码如下

textUserTyped match {
case MoviesZipRE(zip) => getSearchResults(zip)
case MoviesNearCityStateRE(city, state) => getSearchResults(city, state)
case _ => println("did not match a regex")
}

上述的正则表达式可以匹配如下字符串

  80.png

  在匹配时,需要考虑所有情况,如case _ 表示不能匹配,如下字符串将无法匹配

  81.png

  

2.9 访问字符串的字符

  1. 问题描述

  你想要获取字符串中特定位置的字符。

  2. 解决方案

  可以使用Java的charAt方法

  82.png

  另外,一种更好的方法是数组表示法

  83.png

  3. 讨论

  当map方法和foreach不适用时,可以将String看做Array类型,然后使用数组表示法来访问字符,Scala中的数组表示法不同于Java的数组表示法,因为在Scala中,数组表示法是一个方法调用。

  84.png

  在调用数组表示法时实际上调用的是apply方法,,但是由于Scala语法糖的存在,可以直接使用数组表示法获取指定字符。

 

 2.10 向String类添加自定义方法

  1. 问题描述

   你想要向字符串类添加自定义方法,如"HAL".increment,而非使用工具类StringUtilities的increment方法。

  2. 解决方案

  可以定义一个隐式类,然后在类中定义你想要添加的方法

  85.png

  在实际的编码中会稍微复杂一点,因为隐式类需要必须要被定义在可以被定义方法的作用域中,这意味着隐式类必须定义在class、object、package object中。 

package com.leesf.utils
object StringUtils {
    implicit class StringImprovements(val s: String) {
        def increment = s.map(c => (c + 1).toChar)
    }
}    

 在使用时,需要导入com.leesf.utils.StringUtils

package foo.bar
import com.leesf.utils.StringUtils._
object Main extends App {
    println("HAL".increment)
}

 还可将隐式类放在包对象中 

package com.leesf
package object utils {
    implicit class StringImprovements(val s: String) {
        def increment = s.map(c => (c + 1).toChar)
    }
}    

 在使用时,需要导入com.leesf.utils  

package foo.bar
import com.leesf.utils._
object MainDriver extends App {
    println("HAL".increment)
}

针对Scala2.10前的版本,与上述做法有稍许不同,首先需要在普通的类中定义increment方法  

class StringImprovements(val s: String) {
    def increment = s.map(c => (c + 1).toChar)
}

 然后定义隐式方法进行转化  

implicit def stringToString(s: String) = new StringImprovements(s)

3. 讨论

  在Scala中,你可以通过隐式转化向封闭的类添加新的方法,并且在使用时导入,而不需要继承该类来添加方法(有些final类根本不能继承)。


三、总结


  本篇博文讲解了Scala中的String知识点,其也是在Scala编程中使用频率非常高的知识点,对其进行了梳理,加深了印象,也谢谢各位园友的观看~ 

目录
相关文章
|
消息中间件 分布式计算 Java
【Scala】Scala之String(一)
 大数据领域的Spark、Kafka、Summingbird等都是由Scala语言编写而成,相比Java而言,Scala更精炼。由于笔者从事大数据相关的工作,所以有必要好好学习Scala语言,之前也学习过,但是没有记录,所以就会忘记,感觉Scala确实比Java方便精炼很多,下面以Scala Cookbook英文版作为参考资料,从头到尾梳理Scala相关知识点,也加深印象。PS:这是在研究Zookeeper源码的间隙中交叉学习,不至于总是看源码太枯燥。
483 0
【Scala】Scala之String(一)
|
SQL 消息中间件 分布式计算
如何查看spark与hadoop、kafka、Scala、flume、hive等兼容版本【适用于任何版本】
如何查看spark与hadoop、kafka、Scala、flume、hive等兼容版本【适用于任何版本】
917 0
如何查看spark与hadoop、kafka、Scala、flume、hive等兼容版本【适用于任何版本】
|
3月前
|
分布式计算 资源调度 Java
Scala+Spark+Hadoop+IDEA实现WordCount单词计数,上传并执行任务(简单实例-下)
Scala+Spark+Hadoop+IDEA实现WordCount单词计数,上传并执行任务(简单实例-下)
37 0
|
3月前
|
分布式计算 Hadoop Scala
Scala +Spark+Hadoop+Zookeeper+IDEA实现WordCount单词计数(简单实例-上)
Scala +Spark+Hadoop+Zookeeper+IDEA实现WordCount单词计数(简单实例-上)
34 0
|
4月前
|
SQL 存储 分布式计算
在scala中使用spark
在scala中使用spark
227 0
|
4月前
|
分布式计算 Java Scala
spark 与 scala 的对应版本查看、在idea中maven版本不要选择17,弄了好久,换成11就可以啦
spark 与 scala 的对应版本查看、.在idea中maven版本不要选择17,弄了好久,换成11就可以啦
302 2
|
4月前
|
分布式计算 Java Scala
Spark编程语言选择:Scala、Java和Python
Spark编程语言选择:Scala、Java和Python
Spark编程语言选择:Scala、Java和Python
|
4月前
|
分布式计算 数据处理 Scala
Spark 集群和 Scala 编程语言的关系
Spark 集群和 Scala 编程语言的关系
|
存储 分布式计算 Scala
Spark-RDD 键值对的操作(Scala版)
Spark-RDD 键值对的操作(Scala版)