Java & Groovy & Scala & Kotlin - 07.字符串

Overview

本节主要介绍四种语言中的字符串的相关用法。由于字符串的 API 众多,所以本节只挑几个主要的来讲。

Java 篇

声明字面量

String s = "Hello World";

遍历字符串

for (char c : s.toCharArray()) {
    System.out.println(c);
}

多行文本

String text =
        "\t1, 2, 3\n" +
                "\tone, two, three\n" +
                "\t\"x\", \"y\", \"z\"";

在 Java 中表示多行文本和特殊字符时需要使用对应的转义符,看起来很不直观,尤其是碰到表示 XML 或者 JSON 的字符串更是让人头痛。

字符串模板 Template

所谓的字符串模板或者说字符串插值就是使用变量或表达式的结果来代替字符串中的特殊占位符。

Java 语言本身并没有字符串模板,要想实现模板功能只有自己解析字符串,使用 replace() 等方法来进行模拟。

例:

String name = "Peter";
String str = "name=$name, ${name.length()}";
System.out.println(
        str.replace("$name", name)
                .replace("${name.length()}", "" + name.length()));

或者也可以使用 format() 方法来实现

System.out.println(String.format("name=%s, %d", name, name.length()));

总的来说使用起来并不方便。

常用方法

//  获取某一位置的字符
System.out.println(s.charAt(2));    //  l

//  截取子串
System.out.println(s.substring(6, 9));  //  Wor

StringBuilder

由于 Java 中字符串是不可变的,所以直接连接字符串会创建大量对象。因此 Java 提供了非同步版本的 StringBuilder 和同步的 StringBuffer 来用于创建字符串池。

StringBuilder content = new StringBuilder();
content.append("hello");
content.append(",");
content.append("\nworld");
content.append("!").append("!");
System.out.println(content);

需要注意不要使用 append("foo" + "bar") 这样的形式而是使用 append("foo").append("bar"),因为前者完全丧失了 StringBuffer 的功能。

Groovy 篇

声明字面量

def s = "Hello World"

遍历字符

for (c in s) {
    println(c)
}

多行文本

def text =
"""    1, 2, 3
one, two, three
"x, "y", "z\""""

Groovy 中可以使用三个双引号表示按原样输出,即在三个双引号之间可以任意换行,使用特殊字符等,这种设计使 Groovy 中表示 XML 和 JSON 文本时更加简单清晰。

需要注意如果要输出的字符串结尾也是双引号,则必须像以上例子一样在最后一个双引号前加上转义符 "",否则编译器会将此双引号和三个双引号看做是两组双引号而报编译错误。

字符串模板 Template

def name = "Peter"
def str = "name=${name}, ${if (name.length() > 10) 10 else name.length()}"
println(str)    //  name=Peter, 5

Groovy 中可以使用 ${} 来实现字符串模板,大括号之间的字符会被解析为代码并执行,执行的结果会被当做字符串来输出,看起来就像是使用 Javascript 的 eval 函数一样,比起 Java 来说方便许多,再也不用使用一堆加号连接字符串和变量了。

GString

Groovy 和 Javascript 在字符串使用时有一个共同点,就是可用使用单引号或双引号来表示字符串,大部分情况下这两者都是一样的用法。但是使用模板时必须使用双引号,因为包含引用符号 ${} 的以双引号包裹的字符串会被解析为 Groovy 内置的字符串类 GString。该类是 String 类的补充,拥有很多 Groovy 语言的方法。而单引号字符串或不包含引用符号的字符串都会被解析为普通的 Java String 类,也就没有模板等功能了。

常用方法

//  获取某一位置的字符
println(s[2])   //  l

//  截取字符串,"<" 表示不包含
println(s[6..9])    //  Worl
println(s[6..<9])   //  Wor

//  返回从字符串中减去某一部分的新字符串
println(s - "l" - "World")  //  Helo

StringBuilder

Groovy 可以直接使用更简便的符号 << 追加子串。

def content = new StringBuilder()
content.append "hello"
content << ","
content << "\nworld"
content << "!" << "!"

Scala 篇

声明字面量

val s = "Hello World"

遍历字符

for (c <- s) {
  println(c)
}

多行文本

Scala 的多行文本使用方式与 Groovy 基本一致

val text =
  """    1, 2, 3
  one, two, three
  "x, "y", "z""""

字符串模板 Template

Scala 的字符串模板主要依赖于两种插值器(Interpolator):s 插值器和 f 插值器

s 插值器

s 插值器主要用于进行简单的字符串替换,声明时直接使用字符 "s" 连接字符串且当中不要有空格。

val name = "Peter"
val str = s"name=$name, ${if (name.length() > 10) 10 else name.length}"
println(str)  //  name=Peter, 5

f 插值器

f 插值器主要用于进行格式化输出,类似 String.format() 的功能。

val salary = 100.1
println(f"$name%s has $salary%.5f") //  Peter has 100.10000

常用方法

//  获取某一位置的字符
println(s.charAt(2))  //  l

//  截取字符串
println(s.substring(6,9)) //  Wor

StringBuilder

Scala 中除了 append() 方法也可以用重载的操作符进行修改。

val content = new StringBuilder
 content append "hello"
 content += ','
 content ++= "\nworld"
 content ++= "!" ++= "!"

+= 用于添加字符,由于 Scala 中将字符串视为字符的集合所以可以用 ++= 添加字符串。

Kotlin 篇

声明字面量

val s = "Hello World"

遍历字符

for (c in s) {
    println(c)
}

多行文本

同样使用三个引号

val text =
"""     1, 2, 3
    one, two, three
    "x, "y", "z""""

在使用多行文本时可以在字符串中添加边距符号,默认边距符号为 |

val textWithMargin =
            """
            |Tell me and I forget.
    |Teach me and I remember.
|Involve me and I learn.
    |(Benjamin Franklin)
            """.trimMargin()

然后可以使用 trimMargin() 方法去除边距符号和其之前的所有空白字符,通过该种方式可用实现更细致的排版

字符串模板 Template

同样使用 ${} 符号

val name = "Peter"
val str = "name=${name}, ${if (name.length > 10) 10 else name.length}"
println(str)    //  name=Peter, 5

如果希望在字符串模板中使用 $ 符号需要使用 ${'$'} 这样的形式才可以正常显示

"name=${'$'}{name}"

StringBuilder

Kotlin 中可以直接使用内置的 DSL 语句创建可变字符串

val content = buildString {
    append("hello")
    appendln(',') // 添加换行
    append("world")
    append("!", "!") // 添加多参数
}

常用方法

//  获取某一位置的字符
println(s[2])

//  截取字符串
println(s.substring(5, 8))

Summary

  • 除了 Java 之外,其它三种语言都可用使用三个引号实现多行文本
  • 除了 Java 之外,其它三种语言都支持字符串模板,其中 Scala 的语法略微不一样
  • Groovy 支持 String 和对其进行扩展的 GString 两种字符串

文章源码见 https://github.com/SidneyXu/JGSK 仓库的 _07_string 小节

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 前言 由于项目需要用到 Groovy 语言,这两天对其进行了粗略的学习,本文是对学习做的一个简单总结,主要内容参考...
    简单的土豆阅读 188,381评论 12 202
  • 译文:Groovy Language Documentation 文本是由一连串的字符也就是字符串组成,Groov...
    ZJ_Rocky阅读 9,671评论 0 4
  • Groovy是一门基于JVM的动态语言,很多语法和Java类似。大部分Java代码也同时是合法的Groovy代码。...
    乐百川阅读 3,577评论 0 15
  • 1.注释 1.1.单行注释 1.2.多行注释 1.3.GroovyDoc 1.4.Shebang line 2.关...
    勤劳的悄悄阅读 3,531评论 1 13