
7.8 String类常用方法
String类作为项目开发中的重要组成,除了拥有自身的特点之外,它还提供了大量的字符串操作方法。这些方法如表7-1所示,利用这些方法可以方便地实现对字符串内容的处理。
表7-1 String类常用方法

续表

表7-1定义的方法全部来自JavaDoc定义,下面将针对这些方法进行分组解释。
7.8.1 JavaDoc文档简介

JavaDoc是Java官方提供的应用程序编程接口(Application Programming Interface,API)文档,开发者可以根据此文档来获取系统类库的信息。
提示:关于JavaDoc的补充说明。
JavaDoc是在Java开发中接触到的最早文档,该文档建议通过在线方式浏览,考虑到日后开发的需求,尽量阅读英文原版信息。本次使用的是Java10版本文档,地址如下。
Java10文档地址:https://docs.oracle.com/javase/10/docs/api/overview-summary.html。
如果觉得输入以上地址过于麻烦,也可以直接利用搜索引擎输入“java10 api”的形式搜索。
在JDK 1.9之前,所有的Java中的常用类库都会在JVM启动的时候进行全部加载,这样会导致程序启动性能下降。在JDK 1.9开始提供模块化设计,将一些程序类放在了不同的模块里面,所以在进行JavaDoc文档浏览时就会发现如图7-9所示的模块定义。

图7-9 Java模块
在每一个模块中又会包含若干个包,每个包里会定义有不同的类。例如,String类属于java.base模块中java.lang包中定义的类,打开相应的包后就可以发现String类的信息。一般文档里会有以下几个组成部分,如表7-2所示。
表7-2 类的组成部分

续表

7.8.2 字符串与字符

字符串的基本组成单元是字符,在String类中提供有两者转换的处理方法,这些方法如表7-3所示。
表7-3 字符串与字符

范例:观察charAt()方法

本程序中的字符串索引是从0开始的,本程序获取了索引位置为6的字符,实际上就是获取字符串中第7个字符数据。
范例:字符串与字符数组转换

本程序首先将字符串(为了操作方便,此时的字符串全部由小写字母组成)拆分为字符数组;其次使用循环分别处理数组中每一个字符的内容;最后使用String类的构造方法,将字符数组变为字符串对象。
利用字符串与字符数组之间的转换形式也可以实现字符串的组成判断。例如,现在要求判断一个字符串中是否全部由数字所组成,首先将字符串变为字符数组;其次判断每一位的字符范围是否在数字编码范围内('0'~'9')。


范例:判断字符串组成是否全部为数字本程序在主类中定义了一个isNumber()方法,所以此方法可以在主方法中直接调用。在isNumber()方法中为了实现判断,首先将字符串转换为字符数组;其次采用循环的方式判断每一个字符是否是数字(例如,'9'是字符不是数字9),如果有一位不是则返回false(结束判断),如果全部是数字则返回true。
提示:方法命名的习惯。
读者可以发现在本程序中的isNumber()方法返回的是boolean数据类型,这是一种真或假的判断,而在Java开发中,针对返回boolean值的方法习惯性以isXxx()的形式命名。
7.8.3 字符串与字节

字节使用byte描述,字节一般主要用于数据的传输或者进行编码转换,String类就提供了将字符串变为字节数组的操作,目的就是为了方便传输以及编码转换,这些方法如表7-4所示。
表7-4 字符串与字节

范例:字符串与字节转换

本程序利用字节数据类型实现了字符串小写字母转大写字母的操作,首先将字符串利用getBytes()方法变为了字节数组;其次修改数组中每个元素的内容,最终利用String的字符串将修改后的字节数组全部或部分变为字符串。
7.8.4 字符串比较

equals()是最为常用的一个字符串相等判断的比较方法,使用该方法进行比较时只能够判断两个字符串的内容是否完全一致,而除此方法外,也可以使用表7-5所示的方法实现更多的比较判断。
表7-5 字符串内容相等比较

范例:观察大小写比较

本程序首先定义了一个String类对象;其次利用equals()方法进行比较,可以发现equals()是区分大小写的,比较结果为false。而使用equalsIgnoreCase()方法比较是不区分大小写的,结果为true。
equals()和equalsIgnoreCase()两个方法只适用于判断内容是否相等,如果要想比较两个字符串的大小,那么就必须使用compareTo()方法完成,这个方法返回int型数据,这个int型数据有3种结果:大于0(返回结果大于0)、小于0(返回结果小于0)、等于0(返回结果为0)。
范例:观察compareTo()方法


使用compareTo()方法进行大小比较时,会依次比较两个字符串中每个字符的编码内容,并且依据编码的差值得出最终比较结果,而compareToIgnoreCase()方法会忽略大小写实现大小判断。
7.8.5 字符串查找

一个字符串往往由许多字符组成,而如果要从一个完整的字符串中判断某一个子字符串是否存在,可以使用表7-6所示的方法完成。
表7-6 字符串查找

范例:查找子字符串是否存在

contains()方法是从JDK 1.5之后新增加的一个方法。但是在JDK 1.5之前类似的判断只能通过indexOf()方法实现,该方法会进行子字符串索引的查找,最终根据返回结果来判断子字符串是否存在。
范例:使用indexOf()方法判断

本程序利用indexOf()方法实现子字符串索引查找,如果可以找到指定内容就会返回索引数据;如果没有找到子字符串会返回-1。
提示:关于contains()方法实现说明。
String类中的contains()方法是基于indexOf()实现的,源代码如下。

可以发现该方法里调用的正是indexOf()方法。
indexOf()方法在进行字符串查找时,采用的是由前向后顺序查找的,如果需要改变顺序,则可以使用lastIndexOf()方法实现。
范例:使用lastIndexOf()查找

本程序通过lastIndexOf()由后向前检索字符“.”的索引,返回了第一个查找到的索引位置。
范例:判断是否以指定的字符串开头或结尾


本程序分别利用startsWith()与endsWith()两个方法来判断指定的字符串数据是否以指定的内容开头。
7.8.6 字符串替换

在String类中提供有字符串的替换操作,即可以将指定的字符串内容进行整体替换,这些方法如表7-7所示。
表7-7 字符串替换

范例:观察字符串替换

本程序利用replaceAll()与replaceFirst()两个方法实现了全部以及首个内容的替换,特别需要注意的是,这两个方法都会返回替换完成后的新字符串内容。
7.8.7 字符串拆分

字符串拆分操作是指按照一个指定的字符串标记,将一个完整的字符串分割为字符串数组。如果要完成拆分操作,可以使用表7-8所示的方法。
表7-8 字符串拆分

范例:字符串全拆分

本程序是将一个字符串按照空格进行全部拆分,最后将一个完整的字符串拆分为4个子字符串,并且将其保存在String类的对象数组中。
提示:如果split()方法的参数为空字符串则表示根据每个字符拆分。
在进行字符串拆分时,如果split()方法中设置的是一个空字符串,那么就表示全部拆分,即将整个字符串变为一个字符串数组,而数组的长度就是字符串的长度。
范例:字符串全部拆分

此时可以发现,使用split()方法时只设置了一个空字符串(不是null,如果是null则执行会出现NullPointerException异常),空字符串就表示按照每一个字符进行拆分。
范例:拆分为指定长度的数组


本程序在进行拆分时设置了拆分的个数,所以只将全部的内容拆分为两个长度的字符串对象数组。
注意:要避免正则表达式的影响,可以进行转义操作。
实际上,split()方法的字符串拆分能否正常进行都与正则表达式的操作有关,所以有些时候会出现无法拆分的情况,例如,现在给一个IP地址(192.168.1.2),那么首先想到的肯定是根据“.”拆分,而如果直接使用“.”是不可能正常拆分的。
范例:错误的拆分操作

此时是不能够正常执行的,而要想正常执行,必须对要拆分的“.”进行转义,在Java中转义要使用“\\”(“\\”表示一个“\”)描述。
范例:正确的拆分操作

此时程序已经可以正确地实现字符串的拆分操作。而关于正则表达式的内容将在本书第15章为读者讲解。
在实际开发中,拆分操作是非常常见的,因为经常会传递一组数据到程序中进行处理,例如,现在有以下的一个字符串:"张三:20|李四:21|王五:22|..."(姓名:年龄|姓名:年龄|...)。当接收到此数据时必须对数据进行拆分。
范例:复杂拆分


本程序首先使用“|”进行了拆分;其次在每次循环中又使用了“:”继续拆分,最终取得了姓名与年龄数据。在实际开发中,这样的数据传递形式很常见,所以一定要重点掌握。
7.8.8 字符串截取

从一个字符串中可以取出指定的子字符串,称为字符串的截取操作,操作方法如表7-9所示。
表7-9 字符串截取

范例:字符串截取

substring()方法存在重载操作,所以它可以返回两种截取结果,一种是从指定位置截取到结尾;另一种是设置截取的开始索引与结束索引。截取完成后substring()方法会返回截取的结果。
范例:通过字符串索引确定截取范围


本程序是在实际项目开发中较为常见的一种设计思想,即通过既定的结构进行字符串的保存,这样就可以通过一些指定的内容作为索引标记,从而获取所需要的数据信息。
7.8.9 字符串格式化

为了吸引更多的传统开发人员,从JDK 1.5开始Java提供了格式化数据的处理操作,类似于C语言中的格式化输出语句,可以利用占位符实现数据的输出。常用的占位符有字符串(%s)、字符(%c)、整数(%d)、小数(%f)等,格式化字符串的方法如表7-10所示。
表7-10 字符串格式化

范例:格式化字符串

String类中的format()是一个静态方法,可以直接用类名称进行调用,使用各种占位符的标记,并且利用可变参数配置对应内容即可实现字符串格式化处理。
提示:format()方法同C语言的printf()函数功能类似。
当看到printf()方法名称的时候应该首先想到的是C语言中的输出,现在Java也具备了同样的功能,而输出的时候可以使用一些标记来表示要输出的内容。例如,字符串(%s)、整数(%d)、小数(%f)、字符(%c)等,之所以有这样的输出,其实目的还是在于抢夺C语言的开发人员市场。
7.8.10 其他操作方法

在String类中提供了多种处理方法,除了之前给定的几类外,也可以利用自身的方法实现长度计算、空字符串判断、大小写转换等操作,这些操作方法如表7-11所示。
表7-11 其他操作方法

范例:字符串连接

concat()的操作形式与“+”的作用类似,但是需要注意的是,concat()方法在每一次进行字符串连接后都会返回一个新的实例化对象,属于运行时常量,所以与静态字符串常量的内存地址不同。
在字符串定义的时候“""”和null不是一个概念,一个表示有实例化对象,一个表示没有实例化对象,而isEmpty()主要是判断字符串的内容,所以一定要在有实例化对象的时候进行调用。
范例:判断空字符串

本程序利用isEmpty()判断了字符串的内容是否为空,当字符串对象实例化后并且设置内容时会返回true。
范例:观察length()与trim()方法

本程序利用trim()方法去除字符串前后空格。在实际项目中在要求用户输入一些数据信息时(例如,登录时输入用户名和密码)就可以利用此方式来处理输入数据,避免由于错误输入多余的空格而出现的错误。
提示:关于length的说明。
有许多初学者容易把String类中的length()方法(String对象.length())与数组中的length(数组对象.length)属性混淆,在这里一定要提醒读者的是:String中取得字符串长度使用的是length()方法,只要是方法后面都要有“()”;而数组中没有length()方法,只有length属性。
利用编码的数字加减处理可以实现大小写字母的转换操作。针对字符数组大小写转换,传统开发一般会采用循环的方法,该方法会比较麻烦,为此String类提供有大小写转换的方法,利用此方法可以方便地实现字母的大小写转换(非字母不做处理)。
范例:大小写转换

在本程序定义的字符串之中包含有非字母,而执行后可以发现,所有的非字母均没有做任何处理,只是在字母上实现了大小写的转换。
在String类中提供了大部分常见的字符串处理操作方法,但是在实际使用中经常会出现一些特殊要求,例如,将字符串首字母大写,那么这时就需要开发者自行设计方法。
范例:实现首字母大写功能

本程序定义了一个StringUtil工具类,并提供有首字母大写处理方法:initcap()。在initcap()方法中首先对字符串内容进行若干判断,当判断条件满足时利用substring()方法首先截取要转换字符串的第一个字符,其次利用toUpperCase()方法将其变为大写字母,随后再与其他剩余的字符串连接后就可以实现首字母大写的功能了。