【Scala】Scala之String(一)

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

一、前言


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


二、String


  在Scala的REPL环境中测试String的类型,可以发现其就是Java中的String。

     5.png

  所以可以使用Java中String的所有方法,如获取字符串的长度、连接多个字符串。在Scala中,由于String可以被隐式转化成StringOps类型,可将字符串看成一个字符序列,并且可以使用foreach方法遍历字符串的每个字符。

     6.png

  也可将字符串当成字符序列,使用for循环遍历每个字符

     7.png

  同理,也可将字符串当前字节序列,使用for循环遍历

     8.png

  由于字符串可以当成字符顺序集合(字符序列),而在集合上可进行多种操作,如filter

  9.png

  可以看到对字符串进行了过滤,去掉了l字符。filter方法是StringOps的方法,由于String会被隐式的转化为StringOps,因此可以调用此方法。

  对于该隐式转化,是在Perdef对象中定义。 

 

 @inline implicit def augmentString(x: String): StringOps = new StringOps(x)

  向封闭类中添加方法

  在Java中,String被定义成final的,即无法继承String类或者添加任何方法,但在Scala中,我们可以通过隐式转化添加方法,下面例子展示了Scala的String拥有String的特性和集合的特性。

     10.png

  其中,drop方法和take方法都是Scala的序列(集合)的方法,而capitalize方法则是StringOps的方法,这种调用都是通过隐式转化完成的。

  

2.1 测试String的相等性

  1. 问题描述

  你需要比较两个字符串以判断它们是否相等,或者它们包含相同的字符序列。

  2. 解决方案

  定义了如下字符串s1、s2、s3

  11.png

  使用"=="进行相等性判断

  12.png

  可以看到s1、s2、s3均相等,而对于一个好的"=="方法而言,即便是有参数为空,也不会抛出异常。

     13.png

  若在比较过程中不区分大小写,则可将字符串转化成大写或小写进行比较。

  14.png

  然而,在对空字符串调用toUpperCase方法会抛出异常。

  15.png

  在Java中,想要比较不区分大小写比较两个字符串是否相等,则使用equalsIgnoreCase方法

  16.png

  3. 讨论

  在Scala中,我们使用==方法来判定对象的相等性,这与Java不同,Java使用equals方法判定两个对象的相等性,== 是比较两个对象是否是同一个对象(内存地址相同)。在Scala中,== 方法在AnyRef(所有引用类型的父类)中定义,其首先会检查空值,然后再调用第一个对象的equals方法进行比较,因此,当比较两个字符串是否相等时,我们不需要检查空值。

  

2.2 创建多行字符串

  1. 问题描述

  在Scala源码中想要创建多行字符串。

  2. 解决方案

  在Scala中,你可以使用三个双引号来创建多行字符串。  

val s1 = """This is
        a multiline
        String
      """
    println(s1)

3. 讨论

  使用上述方法可以创建多行字符串,但是当打印时,其结果如下 

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替换为" "。

  20.png

  另外,在三引号字符串中可以包含特殊字符,而并不需要转义符进行转义。

    21.png

 

2.3 分割字符串

  1. 问题描述

  你需要使用分割字符来分割字符串,如从逗号分隔(CSV)或管道分隔的文件中获取字符串。

  2. 解决方案

  可以使用String的split方法进行分割

  22.png

  split方法会返回String数组。

  3. 讨论

  split函数的参数可以是正则表达式,所以对于CSV文件,你可以使用逗号进行分割字符串。

  23.png

  可以看到,通过","进行分割时,结果中还包含了一些空格,如" milk", " butter", " Coco Puffs",此时,需要使用trim函数来去掉空格。

  24.png

  我们也可以使用正则表达式来分割字符串

  25.png

  split方法是重载的,一部分从Java的String而来,一部分从Scala的StringLike而来,例如,你可以使用字符而非字符串作为参数来调用split,此时,你使用的是StringLike的方法

  26.png

  此时,使用字符和字符串作为参数两者的结果是相同的。

  

2.4 将变量替换成字符串

  1. 问题描述

  如同Perl、PHP、Ruby一样,你需要将变量替换成字符串。

  2. 解决方案

  为在Scala中使用字符串插值,字符串前面需要使用字母s,同时需要将变量包含在字符串中,而每个变量名前面是一个$字符。

  27.png

  当在字符串前面使用字母s时,表示正在创建一个已处理的字符串字面量,即可以在字符串中直接使用变量。

  字符串字面量中使用表达式

  除了在字符串中使用变量外,同样也可以在字符串中使用表达式,此时表达式需要放在中括号内。


 28.png

0.png

  也可以使用中括号打印对象的属性。

  29.png

  s是一个方法

  放在字符串字面量前面的s实际上是一个方法,而使用s方法可以让你享受如下便利

    · Scala提供了其他现成的插值函数

    · 你可自定义字符串插值函数

  f字符串插值(printf格式)

  在讨论中提到,weight被打印成65,但是如果需要在weight后面增加多位小数点应该怎么做,可以使用f字符串插值方法,其可以格式化字符串中的说明符。 

  30.png

  为使用f字符串插值,首先需要在字符串前面添加f,然后在变量后面使用printf格式化说明符。

  粗插值

  除了使用s和f插值方法外,Scala还包括了粗插值方法,其会保留字符串中的特殊字符。

  31.png

  可以看到使用raw修饰字符串时,其会保留字符串中的特殊字符。

  下表列出了最常用的说明符

  32.png

目录
相关文章
|
消息中间件 分布式计算 搜索推荐
【Scala】Scala之String(二)
 大数据领域的Spark、Kafka、Summingbird等都是由Scala语言编写而成,相比Java而言,Scala更精炼。由于笔者从事大数据相关的工作,所以有必要好好学习Scala语言,之前也学习过,但是没有记录,所以就会忘记,感觉Scala确实比Java方便精炼很多,下面以Scala Cookbook英文版作为参考资料,从头到尾梳理Scala相关知识点,也加深印象。PS:这是在研究Zookeeper源码的间隙中交叉学习,不至于总是看源码太枯燥。
280 0
【Scala】Scala之String(二)
|
3月前
|
分布式计算 大数据 Java
大数据-87 Spark 集群 案例学习 Spark Scala 案例 手写计算圆周率、计算共同好友
大数据-87 Spark 集群 案例学习 Spark Scala 案例 手写计算圆周率、计算共同好友
88 5
|
3月前
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
65 3
|
3月前
|
消息中间件 分布式计算 NoSQL
大数据-104 Spark Streaming Kafka Offset Scala实现Redis管理Offset并更新
大数据-104 Spark Streaming Kafka Offset Scala实现Redis管理Offset并更新
61 0
|
3月前
|
消息中间件 存储 分布式计算
大数据-103 Spark Streaming Kafka Offset管理详解 Scala自定义Offset
大数据-103 Spark Streaming Kafka Offset管理详解 Scala自定义Offset
118 0
|
3月前
|
分布式计算 大数据 Java
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
62 1
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
|
3月前
|
SQL 分布式计算 Java
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
大数据-96 Spark 集群 SparkSQL Scala编写SQL操作SparkSQL的数据源:JSON、CSV、JDBC、Hive
92 0
|
3月前
|
缓存 分布式计算 大数据
大数据-90 Spark 集群 RDD 编程-高阶 RDD容错机制、RDD的分区、自定义分区器(Scala编写)、RDD创建方式(一)
大数据-90 Spark 集群 RDD 编程-高阶 RDD容错机制、RDD的分区、自定义分区器(Scala编写)、RDD创建方式(一)
81 0
|
3月前
|
分布式计算 算法 大数据
大数据-90 Spark 集群 RDD 编程-高阶 RDD容错机制、RDD的分区、自定义分区器(Scala编写)、RDD创建方式(二)
大数据-90 Spark 集群 RDD 编程-高阶 RDD容错机制、RDD的分区、自定义分区器(Scala编写)、RDD创建方式(二)
75 0
|
7月前
|
分布式计算 资源调度 Java
Scala+Spark+Hadoop+IDEA实现WordCount单词计数,上传并执行任务(简单实例-下)
Scala+Spark+Hadoop+IDEA实现WordCount单词计数,上传并执行任务(简单实例-下)
88 0